为什么我得到一个C malloc断言失败?

我正在实现一个分而治之的多项式algorithm,所以我可以将它与OpenCL实现进行基准testing,但是我无法使malloc正常工作。 当我运行程序时,它分配了一堆东西,检查一些东西,然后将size/2发送给algorithm。 然后当我再次打到malloc线时,它吐出这个:

malloc.c:3096:sYSMALLOc:Assertion`(old_top ==(((mbinptr)(((char *)&((av) – > bins [((1) – 1)* 2]))__builtin_offsetof(struct malloc_chunk,fd))))&& old_size == 0)|| ((unsigned long)(old_size)> =(unsigned long)((((_builtin_offsetof(struct malloc_chunk,fd_nextsize))+((2 *(sizeof(size_t))) – 1))&〜((2 * (size_t))) – 1)))&&((old_top) – > size&0x1)&&((unsigned long)old_end&pagemask)== 0)'failed。 中止

有问题的线是:

 int *mult(int size, int *a, int *b) { int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2; fprintf(stdout, "size: %d\n", size); out = (int *)malloc(sizeof(int) * size * 2); } 

我用fprintf检查了大小,它是一个正整数(通常是50)。 我试着用一个普通的数字来调用malloc ,我仍然得到错误。 我只是不知道到底发生了什么事情,到目前为止,Googlefind的一切都是有帮助的。

任何想法是怎么回事? 我试图找出如何编译一个新的GCC万一它是一个编译器错误,但我真的怀疑它。

可能有99.9%的内存已损坏(缓冲区溢出或溢出,释放指针后写入指针,在同一指针上释放两次,等等)

在Valgrind下运行你的代码,看看你的程序做了什么不正确的事情。

为了让你更好地理解为什么发生这种情况,我想对@ r-samuel-klatchko的答案进行一些说明。

当你调用malloc ,真正发生的事情比给你一大块内存玩的更复杂一些。 在底层, malloc还会保留一些关于它给你的内存(最重要的是它的大小)的内务处理信息,这样当你free调用时,它知道有多less内存可以释放。 这些信息通常保存在malloc返回的内存位置之前。 更详尽的信息可以在互联网上find,但(非常)基本的想法是这样的:

 +------+-------------------------------------------------+ + size | malloc'd memory + +------+-------------------------------------------------+ ^-- location in pointer returned by malloc 

在此基础上(大大简化事情),当你调用malloc ,它需要一个指向下一部分内存的指针。 这样做的一个非常简单的方法是查看它给出的前一个内存位置,并将内存中的size字节进一步向下(或向上)移动。 通过这个实现,在分配p1p2p3后,你的内存看起来像这样:

 +------+----------------+------+--------------------+------+----------+ + size | | size | | size | + +------+----------------+------+--------------------+------+----------+ ^- p1 ^- p2 ^- p3 

那么,是什么原因导致你的错误?

那么,想象一下,你的代码错误地写了你已经分配的内存量(或者是因为你分配的比你的问题要less,或者是因为你在代码中使用了错误的边界条件)。 假设你的代码把大量的数据写入p2 ,它开始覆盖p3size字段。 当你下一次调用malloc ,它会查看它返回的最后一个内存位置,查看它的大小字段,移动到p3 + size ,然后开始从那里分配内存。 由于您的代码已被覆盖size ,但是,此内存位置不再在先前分配的内存之后。

不用说,这可以破坏浩劫! 因此, malloc的实现者已经提出了一些“断言”或者检查,试图做一系列的理智检查来抓住这个(以及其他问题),如果它们即将发生的话。 在你的具体情况下,这些断言被违反了,于是malloc中止,告诉你你的代码要做一些它本来不应该做的事情。

如前所述,这是一个过分简单化,但足以说明这一点。 malloc的glibc实现超过5k行,关于如何构build良好的dynamic内存分配机制已经进行了大量的研究,所以将其全部包含在SO回答中是不可能的。 希望这已经给了你一个什么是真正造成这个问题的看法!

你可能超出了分配的地方。 那么直到你调用malloc之前,底层的sw才会启动它

可能会有一个被malloc捕获的守卫值。

编辑…添加这个边界检查帮助

http://www.lrde.epita.fr/~akim/ccmp/doc/bounds-checking.html

我们得到这个错误,因为我们忘了乘以sizeof(int)。 注意malloc(..)的参数是一些字节数,而不是机器字的数量或其他。

我收到以下消息,类似于你的消息:


     (old_top ==(((mbinptr)(((char *)&((av) - > bins [((1) -  1)* 2]))__builtin_offsetof (struct malloc_chunk,fd))))&& old_size == 0)||  ((unsigned long)(old_size)> =(unsigned long)((((_builtin_offsetof(struct malloc_chunk,fd_nextsize))+((2 *(sizeof(size_t))) -  1))&〜((2 * (size_t))) -  1)))&&((old_top) - > size&0x1)&&((unsigned long)old_end&pagemask)== 0)'failed。

在使用malloc的时候,会犯一些错误的方法。 在更新sizeof()之后的因子时,错误地用“+”覆盖了乘号“*” – 运算符将字段添加到无符号字符数组中。

这里是我的情况下的错误代码:


     UCHAR * b =(UCHAR *)malloc(sizeof(UCHAR)+5);
     b [INTBITS] =(某种计算);
     b [BUFSPC] =(有些计算);
     b [BUFOVR] =(一些计算);
     b [BUFMEM] =(一些计算);
     b [MATCHBITS] =(一些计算);

在后面的另一个方法中,我再次使用了malloc,并产生了上面显示的错误消息。 电话(很简单):


     UCHAR * b =(UCHAR *)malloc(sizeof(UCHAR)* 50);

考虑在第一次调用时使用“+” – 符号,这会导致微积分结合立即初始化数组之后(覆盖未分配给数组的内存),给malloc的内存映射带来一些混淆。 因此第二个电话出错了。

我正在将一个应用程序从Visual C移植到Linux上的gcc,我也遇到了同样的问题

malloc.c:3096:sYSMALLOc:在UBUNTU上使用gcc进行声明11。

我把相同的代码移到Suse发行版(在其他计算机上),我没有任何问题。

我怀疑这些问题不在我们的程序中,而是在自己的libc中。

我得到了同样的问题,我使用malloc重新在循环中添加新的char *string数据。 我面临同样的问题,但释放后分配的内存void free()问题进行sorting