我在以下 C 代码中得到了一个奇怪的结果。
int main()
{
int *p = (int *) malloc(100);
p[120] = 5;
printf("\n %d", p[120]);
}
因为我只分配了 100 个字节,这段代码应该会导致段错误。但是,它会打印“5”并且不会给出任何运行时错误。谁能解释一下原因?
最佳答案
不,代码不应(必然)出现段错误。当您尝试访问未分配给您的进程的虚拟内存页面时,会发生段错误。
“堆”或“自由存储”是您的进程拥有的虚拟内存页面区域。 malloc()
API 将该区域 segmentation 为 block 并返回指向该 block 的指针。
如果您的地址超出了您拥有指针的 block 的末尾,您通常会访问属于堆的一部分的内存,而不是您分配的 block 的一部分。通过这种方式,您可以破坏其他堆 block 甚至 malloc()
用于定义堆的数据结构。
有关堆损坏的更多信息,以及在代码的调试版本中检测它的方法,这是一本很棒的书:
Writing Solid Code: Microsoft's Techniques for Developing Bug-Free C Programs by Steve Maguire
Nerd 的补充:在极少数情况下,通过访问堆 block 末尾以外的内存,您可能会访问不属于堆的内存。在这些情况下,您可能会遇到预期的段错误。您可能还会破坏堆之外的其他一些数据结构。这真的是一个机会问题。但是,与典型的堆 block 相比,堆本身非常大,因此 99% 的时间代码(例如您的示例)都会损坏堆。您提供的示例属于 99% 的情况。
关于c - malloc() 和堆内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1751322/