char * a = (char *) malloc(10);
strcpy(a,"string1");
char * x = "string2";
strcat(a,x);
printf("\n%s",a);
在这里,我只将10B分配给a
,但仍然在连接a
和x
(组合大小为16B)之后,C打印答案没有任何问题。
但如果我这样做:
char * a = "string1";
char * x = "string2";
strcat(a,x);
printf("\n%s",a);
然后我得到了一个段错误。为什么是这样?尽管内存分配较低,为什么第一个工作正常? strcat会为我重新分配内存吗?如果是的话,为什么第二个不起作用?是因为a
& x
声明这种方式是不可修改的字符串文字?
答案 0 :(得分:2)
在第一个示例中,a在堆中分配。因此,当您连接另一个字符串时,堆中的某些内容将被覆盖,但没有写保护。
在第二个示例中,指向包含常量的内存区域,并且是只读的。因此,seg故障。
答案 1 :(得分:0)
您的代码正在写入超出其允许的缓冲区,这会导致未定义的行为。这可以工作,它可以失败,更糟糕的是:它看起来像是有效但后来导致看似无关的失败。这种语言允许你做这样的事情,因为你应该知道自己在做什么,但不建议这样做。
在你的第一种情况下,使用malloc来分配缓冲区,你实际上得到了帮助,但不是你应该依赖的方式。 malloc函数至少分配所请求的空间,但实际上它通常会舍入到16的倍数...所以你的malloc(10);
可能是有一个16字节的缓冲区。这是特定于实现的,依靠类似的东西永远不是一个好主意。
在您的第二种情况下,a
(和x
)变量指向的内存可能是不可写的,这就是您的原因所在。我遇到了一个段错误。
答案 2 :(得分:0)
第一个并不总是有效,它已经导致溢出。第二个,a
是一个指向常量字符串的指针,该字符串存储在数据部分的只读页面中。
答案 3 :(得分:0)
在第二种情况下,您所拥有的是pointer
到不可修改的string literals
,
在第一种情况下,您打印的是heap
内存位置,在这种情况下是undefined
,您无法保证每次都能正常工作。
(可能是在一个非常大的循环中写的,你可能会看到这个未定义的行为)