我正在实施鸿沟并征服多项式算法,以便我可以根据OpenCL实现进行基准测试,但我无法获得 malloc 去工作。当我运行程序时,它会分配一堆东西,检查一些东西,然后发送 size/2 到算法。然后,当我击中 malloc 再次排列它:

malloc.c:3096:sysmalloc:断言`(old_top ==(((((mbinptr) malloc_chunk,fd))))&& old_size == 0)|| (((unsigned long)(old_size)> =(unsigned long)(((((((((__ _____endin_offsetof) (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 也有一个简单的数字,我仍然会遇到错误。我只是对正在发生的事情感到困惑,到目前为止,我发现的Google一无所获。

有什么想法发生了什么事?我试图弄清楚如何编译新的海湾合作委员会,以防这是编译器错误,但我真的怀疑。

有帮助吗?

解决方案

99.9%的可能使您的内存破坏(过度或不足的缓冲区,在释放后写信给指针,在同一指针上两次被称为免费,等等)

在下面运行代码 Valgrind 查看您的程序在哪里做的事情不正确。

其他提示

让您更好地了解 为什么 发生这种情况,我想稍微扩展 @r-Samuel-klatchko的答案。

你打电话时 malloc, ,实际上发生的事情比仅仅为您提供大量记忆要玩的要复杂得多。在引擎盖下, malloc 还要保留有关它给您的记忆的一些家政信息(最重要的是,它的大小),以便当您致电时 free, ,它知道有多少记忆可以释放。在内存位置返回给您之前,通常保存此信息 malloc. 。可以找到更多详尽的信息 在Internet™上, ,但是(非常)基本的想法是这样的:

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

在此基础上(并大大简化事物),当您致电时 malloc, ,它需要获取指向可用内存的下一部分的指针。这样做的一种非常简单的方法是查看其赠送的先前记忆,然后移动 size 字节在内存中进一步向下(或向上)。通过此实现,您最终会在分配后看到像这样的东西 p1, p2p3:

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

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

好吧,想象一下,您的代码错误地写出了您分配的内存量(因为您分配了比问题所需的少于所需的,或者是因为您使用了代码中某个地方的错误边界条件)。说您的代码将大量数据写入 p2 它开始覆盖所在 p3' size 场地。现在下一个通话 malloc, ,它将查看其返回的最后一个内存位置,查看其尺寸字段,移至 p3 + size 然后开始从那里分配内存。由于您的代码已覆盖 size, 但是,此内存位置不再是先前分配的内存之后。

不用说,这可能会破坏破坏!实施者 malloc 因此,如果要进行许多“断言”或检查,这些“断言”或检查,试图进行一堆理智检查,以抓住此(以及其他问题),如果它们即将发生。在您的特殊情况下,这些断言是违反的,因此 malloc 流产,告诉您您的代码即将做的事情确实不应该做。

如前所述,这是一个过分简化的,但是足以说明这一点。 GLIBC的实施 malloc 超过5K线,并且已经进行了大量的研究,如何建立良好的动态内存分配机制,因此不可能在SO答案中介绍所有内容。希望这使您对真正导致问题的原因有所了解!

我使用Valgrind的替代解决方案:

我很高兴,因为我只是帮助我的朋友调试程序。他的程序有这个确切的问题(malloc() 引起流产),带有GDB的相同错误消息。

我用他的程序使用 地址消毒剂

gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

然后跑 gdb new. 。当程序终止时 SIGABRT 在随后的 malloc(), ,打印了许多有用的信息:

=================================================================
==407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000000b4 at pc 0x7ffffe49ed1a bp 0x7ffffffedc20 sp 0x7ffffffed3c8
WRITE of size 104 at 0x6060000000b4 thread T0
    #0 0x7ffffe49ed19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x8001dab in CreatHT2 /home/wsl/Desktop/hash/new.c:59
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #4 0x8001679 in _start (/mnt/d/Desktop/hash/new+0x1679)

0x6060000000b4 is located 0 bytes to the right of 52-byte region [0x606000000080,0x6060000000b4)
allocated by thread T0 here:
    #0 0x7ffffe51eb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x8001d56 in CreatHT2 /home/wsl/Desktop/hash/new.c:55
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

让我们看一下输出,尤其是堆栈跟踪:

第一部分说在 new.c:59. 。那条线读取

memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

第二部分说发生了不良写入的记忆是在 new.c:55. 。那条线读取

if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

而已。我只花了不到半分钟的时间来找到我的朋友几个小时混淆的错误。他设法找到了失败,但随后是 malloc() 呼叫失败,而无法在先前的代码中发现此错误。

总结:尝试 -fsanitize=address 海湾合作委员会或clang。在调试内存问题时,它可能非常有帮助。

您可能会超越分配的MEM某个地方。然后,下面的SW直到您致电Malloc之前才捡起它

可能有一个被马洛克捕获的警卫价值。

编辑...添加此范围以进行检查帮助

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

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

    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时,犯错了一些方法。在更新sizeof()之后的因子时,错误地覆盖了乘法符号'*', - 在将字段添加到未签名的char数组时。

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

    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);

在第一个呼叫上使用'+' - 符号,这会导致MIS-Calculus与阵列后立即初始化(未分配给数组的覆盖内存)的立即初始化,这给Malloc的内存图带来了一些混乱。 因此,第二个电话错误。

我们遇到了这个错误,因为我们忘记乘以sizeof(int)乘以。请注意,与malloc(..)的论点是许多字节,而不是机器单词的数量。

我正在通过Linux移植一个从Visual C到GCC的应用程序,我也有同样的问题

Malloc.C:3096:Sysmalloc:在Ubuntu 11上使用GCC的断言。

我将相同的代码移至SUSE分发(在其他计算机上),但没有任何问题。

我怀疑问题不在我们的计划中,而是在自己的libc中。

我遇到了同样的问题,我在循环中再次使用malloc,添加新的char *字符串数据。我遇到了同样的问题,但是在释放了分配的内存之后 void free() 问题已经分类

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top