0

在下面的程序中,

#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)

SIGSEGV 开启str2[1] = 's';

根据我的理解,由于声明,不能修改abc指向的,其中字符串文字是常量。st1const char *st1 = "abc"

为什么char *typestr2不允许修改元素?stringliteraldef也是常量字符串文字。

4

5 回答 5

2

这就是发生的事情:

  1. str2分配malloc()并指向新分配的 4 个字符的缓冲区

  2. 您将 的值(地址)更改str2为 的地址"def",这是只读的(将其视为程序的一部分)

  3. 你尝试改变"def"

  4. 您无法释放内存,因为您在分配str2给地址时实际上丢失了它的地址"def"

于 2016-10-20T05:30:04.713 回答
1

根据 C 标准

字符串文字("def")将存储在数据部分的只读页面中。

所以你不能修改它的内存。


您可以修改str2指针的内容。这意味着您可以将 str2 指向其他内存。但是分配的内存string literal "def"不能修改。


  str2= "def";

通过这样做,您不会在分配的内存中复制“def”。相反,“def”被分配在只读区域中,并且您将其地址分配给 str2。

如果您想将该“def”存储到分配空间中,请使用 memcpy 的 strcpy。

于 2016-10-20T05:30:05.753 回答
0

str2 = "def";语句更改 的值str2str2指向导致以下崩溃的赋值后的字符串文字“def”。至少,在我的 RHEL 7.1 和 gcc 4.8.3 上是这样的

于 2016-10-20T05:28:01.663 回答
0

如果要将“abc”存储在刚刚分配的字符串缓冲区中,则必须使用strcpy(),如strcpy(str2, "abc"). 正如其他用户所指出的那样,使用str2 = "abc"将更改指向的内存地址str2而不是这样做,并且该新地址是指无法修改的只读部分。

于 2016-10-20T05:39:03.333 回答
-1

问题:

  char *str2 = (char *)malloc(sizeof(char)*4);

这意味着您在内存中请求了 4 个字节的空间供您个人使用,并且您已获得该空间的起始地址。

  str2= "def";

您得到了您的个人地址,但现在您正在更改地址以指向迷人的“def”,它属于内存的只读数据部分(字符串文字)。这意味着分配的原始地址是悬空的,无法追溯。

问题:

  • 悬空指针,其中地址将无法追踪。
  • 你将无法释放它。

str2[1]='s';

哦,现在您正试图通过更改只读部分的内容来成为反叛者。

问题:

  • 试图覆盖不允许的只读段。

  • SIGSEGV 是原因,即由无效内存引用或分段错误引起的错误(信号)。

您可能实际上正在尝试的内容:

  • 为您的工作分配内存(4 个字节)
  • 将内容覆盖到该内存strcpy(str2, "def");
  • str2[1] = 's'那时也可以工作。
  • 请释放str2变量,因为您是要求它的人。(权力越大,责任越大);)
于 2016-10-20T06:07:52.513 回答