【发布时间】: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