2

我有这个代码:

#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 的原因)。谁能解释我为什么以及如何发生这种情况?谢谢!

4

4 回答 4

8

线

s = ABC;

更改s为指向可能位于只读内存中的不同字符串。尝试释放此类内存会导致未定义的行为。很可能会发生崩溃。

我想你想要

strcpy(s, ABC);

反而。这会将 char 数组“abc”复制到s. 请注意,这将导致进一步的错误 -s太短并且没有空间用于结尾的 nul 终止符ABC。将分配更改为 4 个字节以解决此问题

char *s = malloc(4);

或使用

char *s = malloc(sizeof(ABC));

ifABC是您要存储的最大长度。

于 2012-11-22T11:28:39.160 回答
3

void main() UBmain返回int

printf("%p", s) UB:调用一个函数,该函数接受可变数量的参数,但范围内没有原型;UB:在需要类型值的char*地方使用类型值void*

free(s) UB : s 不是 a 的结果malloc()

UB未定义的行为

于 2012-11-22T11:30:15.617 回答
3

char *s = malloc(sizeof(char)*3);

s 指向 malloc 分配的内存。

线

s = ABC;

将更改为

s = "abc";

在占有之后。现在这一步s指向"abc"只读区域中的字符串文字。请注意,这也会泄漏分配的内存。

现在由于s指向非分配的只读内存,因此释放它是一种未定义的行为。

如果要将字符串复制"abc"到指向的内存中,则s需要strcpy用作:

strcpy(s, ABC);

但请注意,要容纳"abc",s必须至少有 4 个字符长,以容纳 NUL 字符。

于 2012-11-22T11:31:56.253 回答
0

换行: char *s = malloc(sizeof(char)*3);

char *s = (char *)malloc(sizeof(char)*3);

这清除了许多编译器警告的警告。

不仅如此,我还建议您根据您的工作使您的代码更加灵活。如果由于某种原因您将 ABC 更改为“ABCD”,您将没有为所有字符分配足够的空间。

此外,字符串“ABC”实际上有 4 个字符(因为末尾有一个空字符来终止字符串)。如果没有那个额外的终结符,你会看到问题。

于 2012-11-22T14:56:28.173 回答