关于修改 char * 元素的 SIGSEGV
SIGSEGV on modifying char * element
在下面的程序中,
#include<stdio.h>
#include<stdlib.h>
int main(){
const char *str1 = "abc";
char *str2 = (char *)malloc(sizeof(char)*4);
str2= "def";
str2[1]='s';
printf("str2 is %s", str2);
}
调试器:
(gdb) ptype str1
type = const char *
(gdb) ptype str2
type = char *
(gdb) n
7 str2[1]='s';
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005ab in main () at main.c:7
7 str2[1]='s';
(gdb)
str2[1] = 's';
上的 SIGSEGV
根据我的理解,由于声明 const char *st1 = "abc"
,无法修改 st1
指向的 abc
,其中字符串文字是常量。
为什么char *
类型str2
不允许修改元素? stringliteral def
也是常量字符串文字吗
str2 = "def";
语句更改了 str2
的值。 str2
指向导致以下崩溃的赋值后的字符串文字 "def" 。至少,在我的 RHEL 7.1 和 gcc 4.8.3
上是这样
事情就是这样:
str2
分配了malloc()
并指向新分配的4个字符的缓冲区
您将 str2
的值(地址)更改为 "def"
的地址,这是只读的(将其视为程序的一部分)
你试试改"def"
您无法释放内存,因为当您将 str2
分配给 "def"
[= 的地址时,您实际上丢失了它的地址32=]
按照 C 标准
字符串文字("def")
将存储在数据部分,在只读页面中。
所以你不能修改它的内存。
可以修改str2
指针的内容。这意味着您可以将 str2 指向其他内存。但是分配给 string literal "def"
的内存无法修改。
str2= "def";
通过这样做,您不会在分配的内存中复制 "def"。
相反,"def" 被分配到只读区域,您将其地址分配给 str2.
如果你想将 "def" 存储到 malloced space 然后使用
memcpy 的 strcpy.
如果要将"abc"存储在刚刚分配的字符串缓冲区中,则必须使用strcpy()
,如strcpy(str2, "abc")
。正如其他用户指出的那样,使用 str2 = "abc"
将更改 str2
指向的内存地址而不是这样做,并且新地址指的是无法修改的只读部分。
问题:
char *str2 = (char *)malloc(sizeof(char)*4);
This means that you have asked for 4 bytes of space in the memory for your personal use and you have been granted with the starting address of the space.
str2= "def";
You got your personal address but now you are changing your address to point to the enchanting "def" which belongs to Read-Only Data section of the memory (String literals). This means that the original address allocated is dangling and cannot be traced back.
问题:
- 地址无法追踪的悬挂指针。
- 您将无法释放它。
str2[1]='s';
Ohh and now you are trying to be a rebel by trying to change the read only section's content.
问题:
正在尝试覆盖不允许的只读段。
SIGSEGV 是原因,即由无效内存引用或分段错误引起的错误(信号)。
您可能正在尝试的是:
- 为您的工作分配内存(4 个字节)
- 覆盖内存中的内容
strcpy(str2, "def");
str2[1] = 's'
也可以。
- 请释放
str2
变量,因为您是请求它的人。 (能力越大,责任越大);)
在下面的程序中,
#include<stdio.h>
#include<stdlib.h>
int main(){
const char *str1 = "abc";
char *str2 = (char *)malloc(sizeof(char)*4);
str2= "def";
str2[1]='s';
printf("str2 is %s", str2);
}
调试器:
(gdb) ptype str1
type = const char *
(gdb) ptype str2
type = char *
(gdb) n
7 str2[1]='s';
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005ab in main () at main.c:7
7 str2[1]='s';
(gdb)
str2[1] = 's';
根据我的理解,由于声明 const char *st1 = "abc"
,无法修改 st1
指向的 abc
,其中字符串文字是常量。
为什么char *
类型str2
不允许修改元素? stringliteral def
也是常量字符串文字吗
str2 = "def";
语句更改了 str2
的值。 str2
指向导致以下崩溃的赋值后的字符串文字 "def" 。至少,在我的 RHEL 7.1 和 gcc 4.8.3
事情就是这样:
str2
分配了malloc()
并指向新分配的4个字符的缓冲区您将
str2
的值(地址)更改为"def"
的地址,这是只读的(将其视为程序的一部分)你试试改
"def"
您无法释放内存,因为当您将
[= 的地址时,您实际上丢失了它的地址32=]str2
分配给"def"
按照 C 标准
字符串文字("def")
将存储在数据部分,在只读页面中。
所以你不能修改它的内存。
可以修改str2
指针的内容。这意味着您可以将 str2 指向其他内存。但是分配给 string literal "def"
的内存无法修改。
str2= "def";
通过这样做,您不会在分配的内存中复制 "def"。 相反,"def" 被分配到只读区域,您将其地址分配给 str2.
如果你想将 "def" 存储到 malloced space 然后使用 memcpy 的 strcpy.
如果要将"abc"存储在刚刚分配的字符串缓冲区中,则必须使用strcpy()
,如strcpy(str2, "abc")
。正如其他用户指出的那样,使用 str2 = "abc"
将更改 str2
指向的内存地址而不是这样做,并且新地址指的是无法修改的只读部分。
问题:
char *str2 = (char *)malloc(sizeof(char)*4);
This means that you have asked for 4 bytes of space in the memory for your personal use and you have been granted with the starting address of the space.
str2= "def";
You got your personal address but now you are changing your address to point to the enchanting "def" which belongs to Read-Only Data section of the memory (String literals). This means that the original address allocated is dangling and cannot be traced back.
问题:
- 地址无法追踪的悬挂指针。
- 您将无法释放它。
str2[1]='s';
Ohh and now you are trying to be a rebel by trying to change the read only section's content.
问题:
正在尝试覆盖不允许的只读段。
SIGSEGV 是原因,即由无效内存引用或分段错误引起的错误(信号)。
您可能正在尝试的是:
- 为您的工作分配内存(4 个字节)
- 覆盖内存中的内容
strcpy(str2, "def");
str2[1] = 's'
也可以。- 请释放
str2
变量,因为您是请求它的人。 (能力越大,责任越大);)