Malloc疑问:为何小内存分配的字符串能容纳长文本且不segfault?
为什么这段代码不会触发 Segfault?
咱们先把你的代码再贴一遍,方便对照分析:
int main(void) { char *s = malloc(sizeof(char) * 5); s = "Hello world !"; printf("%s\n", s); }
核心问题出在你误解了指针s的指向变化,咱们一步步拆解来看:
第一步:
char *s = malloc(sizeof(char) * 5);
这行确实给s分配了一块能存5个字符的堆内存,此时s指向这块堆空间的起始地址。第二步:
s = "Hello world !";
这是关键的误区!你不是把字符串内容拷贝到刚才malloc的内存里,而是直接把指针s的指向改成了字符串字面量"Hello world !"的地址。这个字符串字面量是存储在程序的只读数据段(完全不是你刚才malloc的堆内存),而且它的内存是程序启动时就合法预留的,属于进程的有效内存范围。第三步:
printf("%s\n", s);
此时s指向的是完全合法的字符串字面量,所以printf能正常打印整个字符串——你之前malloc的那块5字节内存甚至已经被“弄丢”了(内存泄漏),因为你没有保存它的地址,再也没法调用free释放它了,而程序自始至终都没访问过那块内存。
那什么时候才会触发Segfault?
如果你的代码改成这样,试图把字符串内容拷贝到malloc的5字节内存里:
int main(void) { char *s = malloc(sizeof(char) * 5); strcpy(s, "Hello world !"); // 这里才会越界写入内存 printf("%s\n", s); }
这时候就很可能触发Segfault(或者出现其他未定义行为),因为你往只有5字节的堆内存里写入了远超过其容量的内容,越界访问了不属于你的内存区域。
总结一下:你的代码根本没用到那块5字节的堆内存,自然不会因为它的大小不够而触发Segfault——真正访问的是合法存在的字符串字面量内存。
内容的提问来源于stack exchange,提问作者l-portet
相关产品推荐
相关产品推荐

