【问题标题】:Debugging malloc(): memory corruption on new调试 malloc():new 上的内存损坏
【发布时间】:2020-05-28 09:04:14
【问题描述】:

我有一个结合了 Fortran 和 C++ 的中小型应用程序。主要是用 Fortran 编写的,但一个模块是用 c++ 编写的。该模块返回指向存储在 Fortran 大小上的类对象的指针。在创建这些指针之一期间,系统抛出以下错误:

malloc(): memory corruption

Thread 1 "bc_test" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff4a60801 in __GI_abort () at abort.c:79
#2  0x00007ffff4aa9897 in __libc_message (action=action@entry=do_abort, 
    fmt=fmt@entry=0x7ffff4bd6b9a "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff4ab090a in malloc_printerr (
    str=str@entry=0x7ffff4bd4e0e "malloc(): memory corruption") at malloc.c:5350
#4  0x00007ffff4ab4994 in _int_malloc (av=av@entry=0x7ffff4e0bc40 <main_arena>, 
    bytes=bytes@entry=44) at malloc.c:3738
#5  0x00007ffff4ab72ed in __GI___libc_malloc (bytes=44) at malloc.c:3065
#6  0x00007ffff50bc298 in operator new(unsigned long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x0000555555578967 in My_Class::My_Class(this=0x7fffffffd4e0, n=11)
    at /home/.../my_class.cpp:20

使用 gdb 我发现在调用 new 时会引发错误。更具体地说,在通过 new 创建的对象的构造函数中调用 new (基本的 new 调用按预期工作)。抛出错误的行如下:

int* test  = new int[n];

在这种情况下,n 是一个整数,n=11。

我认为问题不是由于内存不足,因为此时我只分配了 2 个小类实例和一些基本变量。如果这是问题所在,我也相信这会引发不同的错误。

很遗憾,我还没有设法创建 MWE。我现在已经没有如何解决这个问题的想法了。什么会导致此错误?除了找到抛出错误的行之外,如何调试它?

有关“malloc(): memory corruption”错误的其他堆栈溢出结果是由于访问未分配的内存造成的,但这里不是这种情况,因为它是分配调用本身引发了错误。

【问题讨论】:

  • 您在程序启动和发生这种情况之间的某个时间点损坏了内存。不幸的是,不可能比这更具体。
  • C++ 并不总是对调试友好。如果通过越界访问数组或取消引用悬空指针(或...)在程序中的某处调用 UndefinedBehaviour,即使在良好且正确的指令上也可能在稍后发生崩溃。我不知道在 C++ 模块中找到 UB 的辅助方法:您必须仔细控制所有访问(除非首先删除所有可能的警告,如果还有一些警告)
  • 所以问题出在其他地方?这是有道理的,因为这条线看起来不错。你认为它可以用 valgrind 或类似的工具进行调试吗?
  • 尝试使用 address sanitizer 和/或 Valgrind。另外,您是否在没有优化和调试信息的情况下进行编译?
  • 你说得对,我在别处破坏了内存。我发现了 Valgrind 的错误。谢谢大家:)如果有人想创建一个建议的答案,那么我会接受它

标签: c++ memory-management


【解决方案1】:

内存损坏错误并不总是在错误发生的地方表现出来。因此,gdb 回溯通常对于查找错误是无用的。相反,应该使用内存分析/调试工具,例如 Valgrind。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2011-06-04
    相关资源
    最近更新 更多