在以下程序中,
#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';
根据我的理解,由于声明abc
,字符串文字是常量,因此无法修改st1
所指向的const char *st1 = "abc"
。
为什么char *
类型str2
不允许修改元素? stringliteral def
也是一个常量字符串文字。
答案 0 :(得分:2)
发生了什么:
str2
分配有malloc()
并指向新分配的4个字符的缓冲区
您将str2
的值(地址)更改为"def"
的地址,该地址为只读(将其视为您计划的一部分)
您尝试更改"def"
您无法释放内存,因为当您将str2
分配到"def"
答案 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是由无效的内存引用或分段错误引起的错误(信号)的原因。
你可能正在尝试的是什么:
strcpy(str2, "def");
str2[1] = 's'
也适用。str2
变量,因为您是要求它的人。 (以强大的力量来承担很大的责任);)