2010-10-13 173 views
4
int main() 
{ 
    int * b; 
    b = (int*) malloc (1); 
    *b=110000; 
    free (b); 
    return 0; 
} 

为什么堆腐败发生在free (b);C中的堆损坏

IMO,堆腐败已发生在*b=110000;

+2

仅供参考,您不需要投射malloc。 – Nyan 2010-10-13 13:35:16

+0

你跟Valgrind核对过吗?这将告诉你在哪里发生了非法写入,这应该是上述示例中的第5行。 – Christoffer 2010-10-13 14:28:09

回答

12

malloc()的参数是要分配的字节数。您需要使用:

b = (int*) malloc(sizeof(int)); 

您已经分配过小的块,然后写比你分配,其旁边块覆盖簿记信息,损坏堆更多的字节给它。

+0

我的问题是为什么'* b = 110000;'因为它使用的空间比可用空间更多而没有损坏? – Alan 2010-10-13 11:55:39

+14

腐败堆的任务是检测腐败的免费调用。 – 2010-10-13 11:58:00

+1

@Alan - 它会破坏你的堆。只是你可能会立即看到后果,也可能看不到后果。 – 2010-10-13 11:58:43

5

它在* b = 110000;因为您正在为一个字节分配内存,然后为其分配一个不止一个字节的int。要么你可以有b =(int *)malloc(sizeof(int)),而不是int * b,你可以有char * b,然后将指针指向char *。如果您为* b分配的值小于128(由于signed char),代码甚至可能会工作。

编辑: - 我认为有时甚至这将工作没有任何麻烦。因为编译器可能会选择分配多个字节的内存来快速访问数据。

4

堆腐败确实发生在*b=11000分配上,但直到free(b)调用才被检测到,因为这是再次检查堆完整性的第一个点。

检查每个赋值(甚至每个涉及解引用指针的赋值)时的堆完整性会使大多数程序减慢太多,并且会使编译器与库实现紧密联系在一起。出于这个原因,完整性检查仅在堆被操纵时执行,这在mallocfree函数(和朋友)中。

0

代码将更多数据写入内存块,而不是可用空间,因此会破坏下一个有效内存块的开始。

使用char *而不是int *并写入值-128到127到* b应该修复它。