c++ - 使用 "new"关键字时 sYSMALLOc 断言失败

标签 c++ gdb new-operator valgrind

EDIT: For clarity's sake, I'll leave the question as it is. The problem seems to be that the Kameleon class uses boost, and since my own code also uses it there are probably conflicting versions and that's where the problems come from.

原始问题:

很多信息,但我已尝试将其归结为有趣的部分。我正在编写一个应用程序,它使用 Kameleon 类的实例(不是我自己编写的)来执行各种任务。当我尝试使用 new 关键字分配实例时,我遇到了麻烦。这是问题的缩小版本:

#include <ccmc/Kameleon.h>

int main() {
  ccmc::Kameleon k;
  ccmc::Kameleon *k2 = new ccmc::Kameleon(); // <-- crashes with this line
  delete k2:
  return 0;
 }

旁注:注释掉 k2new 分配并仅运行 ccmc::Kameleon k 有效,我可以使用变量.但是,当我尝试这样做时,当 main() 返回时程序会出现段错误。析构函数什么都不做。

`Kameleon 构造函数执行以下操作:

// Kameleon.cpp
/*47*/ Kameleon::Kameleon() : model(NULL), // model is a non-const pointer 
/*48*/                        modelName("NA"), // modelName is a non-const std::string
/*49*/                        missingValue(0.f) // missingValue is a non-const float
/*50*/ {}

我已尝试使用错误消息、gdb 和 valgrind 解决我的问题,但似乎无法找到源头。这是运行程序给我的结果:

FurnaceApp: malloc.c:2451: 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.
Aborted (core dumped)

gdb 告诉我以下内容:

(gdb) bt
#0  0x00007ffff6b1c425 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff6b1fb8b in __GI_abort () at abort.c:91
#2  0x00007ffff6b6415d in __malloc_assert (assertion=<optimized out>, file=<optimized out>, line=<optimized out>, function=<optimized out>)
    at malloc.c:300
#3  0x00007ffff6b67664 in sYSMALLOc (av=0x7ffff6e9e720, nb=48) at malloc.c:2448
#4  _int_malloc (av=0x7ffff6e9e720, bytes=27) at malloc.c:3892
#5  0x00007ffff6b68fb5 in __GI___libc_malloc (bytes=27) at malloc.c:2924
#6  0x00007ffff746cded in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff7455a89 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff7457495 in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x00007ffff74575e3 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00007ffff7757caf in ccmc::Kameleon::Kameleon (this=0x67d920) at Kameleon.cpp:49
#11 0x0000000000415516 in main ()

最后,valgrind 给了我很多输出,但是这部分看起来最像前面的错误:

==11789== Invalid write of size 8
==11789==    at 0x52ECC8D: ccmc::Kameleon::Kameleon() (buckets.hpp:128)
==11789==    by 0x415515: main (in /home/vsand/OpenSpace/Furnace/FurnaceApp)
==11789==  Address 0x6683a00 is 0 bytes after a block of size 464 alloc'd
==11789==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11789==    by 0x41550A: main (in /home/vsand/OpenSpace/Furnace/FurnaceApp)
==11789== 
==11789== Invalid write of size 8
==11789==    at 0x52ECC94: ccmc::Kameleon::Kameleon() (table.hpp:226)
==11789==    by 0x415515: main (in /home/vsand/OpenSpace/Furnace/FurnaceApp)
==11789==  Address 0x6683a28 is not stack'd, malloc'd or (recently) free'd
==11789== 
==11789== Invalid write of size 8
==11789==    at 0x52ECC9F: ccmc::Kameleon::Kameleon() (Kameleon.cpp:49)
==11789==    by 0x415515: main (in /home/vsand/OpenSpace/Furnace/FurnaceApp)
==11789==  Address 0x6683a30 is not stack'd, malloc'd or (recently) free'd
==11789== 

环顾四周,这些错误似乎通常是在不正确地使用 malloc 和写入超出分配的内存等时出现的。Kameleon 中有很多代码类,但由于不是我自己写的,所以我很难找到它。任何错误查找提示将不胜感激!

最佳答案

==11789== Invalid write of size 8
==11789==    at 0x52ECC8D: ccmc::Kameleon::Kameleon() (buckets.hpp:128)
==11789==    by 0x415515: main (in /home/vsand/OpenSpace/Furnace/FurnaceApp)
==11789==  Address 0x6683a00 is 0 bytes after a block of size 464 alloc'd
==11789==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11789==    by 0x41550A: main (in /home/vsand/OpenSpace/Furnace/FurnaceApp)

这意味着:

  • 分配 ccmc::Kameleon 实例的代码认为 sizeof(ccmc::Kameleon) 是 464,而
  • 实际实现 ccmc::Kameleon::Kameleon() 的代码写入字节 [this+464, this+472)

最可能的原因:

  • 您已经更改了 buckets.hpp 中类的定义,并且
  • 您没有重新编译所有 使用它的代码,因此违反了one definition rule .

必须重建所有使用Kameleon 的代码,一旦您这样做,您的问题就会消失。

buckets.hpp is from boost headers

另一种可能性是您正在链接针对不同版本的 Boost 编译的库。那不能工作,您必须使用完全相同版本的 Boost。

最后一种可能性是 Boost 是用一组不一致的 -DXX 标志编译的,导致 Kameleon 类的不同定义(再次违反了一个定义规则).

关于c++ - 使用 "new"关键字时 sYSMALLOc 断言失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16156347/

相关文章:

c - 调试子进程不适用于 set detach-on-fork off

c++ - GDB/DDD 当前上下文中没有符号 <var>

linux - GDB:linux 内置模块中的断点失败

java - 为什么我们不需要在 main 方法中声明 new 来创建 Err 对象?

c++ - 在同一代码中放置新的和新的

c++ - 在 C++ 中打印 (2^n 的阶乘)/(2^n -1)mod m

c++ - "explicit"和 "implicit"调用operator()的区别

c++ - 如何直接使用 OleDB 创建并执行 SQL 命令?

java - Java 创建对象时速度慢吗?

java - 获取html文档中包含word的节点