首页 文章

为什么我的C malloc断言失败了?

提问于
浏览
63

我正在实现一个除法和征服多项式算法,所以我可以对OpenCL实现进行基准测试,但我不能让 malloc 工作 . 当我运行程序时,它会分配一堆东西,检查一些东西,然后将 size/2 发送给算法 . 然后,当我再次点击 malloc 行时,它会吐出这个:

malloc.c:3096:sYSMALLOc:断言`(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 *(sizeof( size_t))) - 1)))&&((old_top) - > size&0x1)&&((unsigned long)old_end&pagemask)== 0)'失败 . 中止

有问题的一行是:

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 ,但我仍然得到错误 . 我已经开始了,到目前为止我发现的谷歌没有任何帮助 .

有什么想法正在发生什么?我试图找出如何编译一个更新的GCC,以防它是一个编译错误,但我真的怀疑它 .

7 回答

  • 0

    99.9%的可能是你有内存损坏(缓冲区流量过大或流量不足,在释放后写入指针,在同一指针上调用两次,等等)

    Valgrind下运行您的代码,以查看您的程序执行错误的位置 .

  • 1

    为了让您更好地理解为什么会发生这种情况,我会回答一下 .

    当你调用 malloc 时,真正发生的事情比给你一大块内存要复杂一点 . 在引擎盖下, malloc 还会保留一些关于它给你的内存(最重要的是它的大小)的内务处理信息,这样当你调用 free 时,就会知道要释放多少内存 . 此信息通常保存在 malloc 返回给您的内存位置之前 . 可以找到更详尽的信息on the internet™,但(非常)基本的想法是这样的:

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

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

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

    那么,是什么导致了您的错误?

    好吧,想象一下你的代码错误地写了你的代码中使用错误边界条件的内存量 . 假设您的代码将如此多的数据写入 p2 ,它开始覆盖 p3size 字段中的内容 . 当您现在接下来调用 malloc 时,它将查看它返回的最后一个内存位置,查看其大小字段,移至 p3 + size 然后从那里开始分配内存 . 但是,由于您的代码已覆盖 size ,因此该内存位置不再位于先前分配的内存之后 .

    毋庸置疑,这可能会造成严重破坏!因此, malloc 的实现者已经输入了许多"assertions"或检查,如果它们即将发生,它们会尝试进行一系列健全性检查以捕获这个(以及其他问题) . 在您的特定情况下,这些断言被违反,因此 malloc 中止,告诉您您的代码即将执行它不应该做的事情 .

    如前所述,这是一个粗略的过度简化,但足以说明这一点 . malloc 的glibc实现超过5k行,并且已经有大量关于如何构建良好的动态内存分配机制的研究,因此无法在SO答案中覆盖它 . 希望这能让您对实际导致问题的原因有所了解!

  • 76

    你可能在某个地方超出分配的内存超出范围 . 然后在你调用malloc之前,底层的sw不会接收它

    可能有一个被malloc捕获的防御值被破坏 .

    编辑...为边界检查帮助添加了这个

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

  • 2

    我得到了以下消息,类似于您的消息:

    program: malloc.c:2372: 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 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
    

    使用malloc时,之前调用了一些方法错误 . 在将字段添加到unsigned char数组时,在sizeof() - 运算符后更新因子时,错误地将乘法符号'*'覆盖为'' .

    以下是我的案例中负责错误的代码:

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5);
        b[INTBITS]=(some calculation);
        b[BUFSPC]=(some calculation);
        b[BUFOVR]=(some calculation);
        b[BUFMEM]=(some calculation);
        b[MATCHBITS]=(some calculation);
    

    在后来的另一种方法中,我再次使用了malloc,它产生了上面显示的错误消息 . 电话是(简单):

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

    Think using the '+'-sign on the 1st call, which lead to mis-calculus in combination with immediate initialization of the array after (overwriting memory that was not allocated to the array), brought some confusion to malloc's memory map. 因此第二次通话出错了 .

  • 2

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

  • 52

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

    malloc.c:3096:sYSMALLOc:在UBUNTU 11上使用gcc断言 .

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

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

  • 0

    我遇到了同样的问题,我在一个循环中使用malloc over n再次添加新的char *字符串数据 . 我面临同样的问题,但在释放分配的内存void free()问题后进行了排序

相关问题