我有这段代码:
#define ABC "abc"
void main()
{
char *s = malloc(sizeof(char)*3);
printf("%p ", s);
s = ABC;
printf("%p ", s);
free(s);
}
这是输出:
0x8927008 0x8048574 Segmentation fault (core dumped)
正如您所看到的,字符串s的地址在赋值后会发生变化(我认为这就是free()给出segfault的原因)。 谁能解释我为什么以及如何发生这种情况? 谢谢!
答案 0 :(得分:8)
该行
s = ABC;
将s
更改为指向可能位于只读内存中的其他字符串。尝试释放此类内存会导致未定义的行为。可能会崩溃。
我想你想要
strcpy(s, ABC);
代替。这会将char数组“abc”复制到s
。请注意,这会导致进一步的错误 - s
太短,并且ABC
末尾的nul终结符没有空间。将分配更改为4个字节以修复此
char *s = malloc(4);
或使用
char *s = malloc(sizeof(ABC));
如果ABC
是您要存储的最大长度。
答案 1 :(得分:3)
void main()
UB :main
返回int
printf("%p", s)
UB :调用一个函数接受可变数量的参数而不在范围内使用原型; UB :使用char*
类型的值,其值为void*
。
free(s)
UB :s不是malloc()
UB 是Undefined Behaviour。
答案 2 :(得分:3)
在
char *s = malloc(sizeof(char)*3);
指向malloc分配的内存。
该行
s = ABC;
将更改为
s = "abc";
在预先考虑之后。现在,此步骤使s
指向只读区域中的字符串文字"abc"
。请注意,这也会泄漏malloced内存。
现在,因为s
指向非malloced只读内存,所以它是一个未定义的行为。
如果您想将字符串"abc"
复制到s
指向的内存中,则需要使用strcpy
:
strcpy(s, ABC);
但请注意,为了容纳"abc"
,s
必须至少包含4个字符,以适应NUL字符。
答案 3 :(得分:0)
更改行:char * s = malloc(sizeof(char)* 3);
到
char * s =(char *)malloc(sizeof(char)* 3);
这清除了许多编制者警告的警告。
除此之外,我建议您根据自己的工作使代码更加灵活。如果由于某种原因将ABC更改为“ABCD”,则不会为所有字符分配足够的空间。
此外,字符串“ABC”实际上有4个字符(因为终止字符串的末尾有一个空值)。如果没有额外的终结器,你会看到问题。