SIGSEGV修改char *元素

时间:2016-10-20 05:18:16

标签: c pointers malloc char-pointer

在以下程序中,

#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

根据我的理解,由于声明abc,字符串文字是常量,因此无法修改st1所指向的const char *st1 = "abc"

为什么char *类型str2不允许修改元素? stringliteral def也是一个常量字符串文字。

5 个答案:

答案 0 :(得分:2)

发生了什么:

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

  2. 您将str2的值(地址)更改为"def"的地址,该地址为只读(将其视为您计划的一部分)

    < / LI>
  3. 您尝试更改"def"

  4. 您无法释放内存,因为当您将str2分配到"def"

  5. 时,您实际上已丢失了内存地址

答案 1 :(得分:1)

根据C标准

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

所以你无法修改它的记忆。

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

  str2= "def";

通过这样做,你不会复制&#34; def&#34;在你的malloced内存中。 相反&#34; def&#34;在只读区域中分配,并将其地址分配给str2。

如果你想存储&#34; def&#34;在malloced空间然后使用 memcpy的strcpy。

答案 2 :(得分:0)

str2 = "def";语句会更改str2的值。 str2指向字符串文字&#34; def&#34;在分配导致以下崩溃之后。至少,在我的RHEL 7.1上使用gcc 4.8.3

答案 3 :(得分:0)

如果你想存储&#34; abc&#34;在刚刚分配的字符串缓冲区中,您必须使用strcpy(),如strcpy(str2, "abc")中所示。正如其他用户所指出的那样,使用str2 = "abc"将改变内存地址str2而不是这样做,而新地址指的是一个无法修改的只读部分。

答案 4 :(得分:-1)

的问题:

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

这意味着您要求内存中有4个字节的空间供您个人使用,并且您已被授予该空间的起始地址。

  str2= "def";
  

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

的问题:

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

str2[1]='s';

  

哦,现在你试图改变只读部分的内容,试图成为反叛者。

问题:

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

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

你可能正在尝试的是什么:

  • 为您的工作分配内存(4个字节)
  • 将内容覆盖到该内存strcpy(str2, "def");
  • str2[1] = 's'也适用。
  • 请释放str2变量,因为您是要求它的人。 (以强大的力量来承担很大的责任);)