【问题标题】:Memory Allocation Error Caused by Inserting into std::vector插入 std::vector 导致的内存分配错误
【发布时间】:2016-02-06 15:23:32
【问题描述】:

作为大学项目的一部分,我正在从头开始编写文本编辑器。我为构建维护核心数据结构而编写的代码存在问题。

以下是我的源代码,gcc/g++ 给我的错误,以及我从 gdb 获得的堆栈跟踪。下面我将详细介绍我的设计。

是的,我确实对 Document::insertChar 中的所有打印和详细声明感到难过。起初我认为这可能是一个初始化问题。而且我还在学习 gdb。

但重要的是,temp.push_back(lnd);和 Lines.insert(iter, nline); (lnd is originall nLine) 都导致同样的错误。

源代码

Document.cpp : http://pastebin.com/LgGHmir8
Line.cpp : http://pastebin.com/BBhbnxUt

(代码从未在非 Linux 平台上测试过,使用 g++ 构建可能无法使用其他编译器)

错误:

test: malloc.c:2388: 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 & (pagesize - 1)) == 0)' 失败。 中止(核心转储)

堆栈跟踪:

(gdb) backtrace
#0  0x00007ffff71d45f8 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff71d5a7a in abort () from /usr/lib/libc.so.6
#2  0x00007ffff7218468 in __malloc_assert () from /usr/lib/libc.so.6
#3  0x00007ffff721a056 in sysmalloc () from /usr/lib/libc.so.6
#4  0x00007ffff721b0a6 in _int_malloc () from /usr/lib/libc.so.6
#5  0x00007ffff721c3d4 in malloc () from /usr/lib/libc.so.6
#6  0x00007ffff7ae70e8 in operator new (sz=24) at /build/gcc/src/gcc-5.3.0/libstdc++-v3/libsupc++/new_op.cc:50
#7  0x0000000000401f15 in __gnu_cxx::new_allocator<Line>::allocate (this=0x7fffffffe950, __n=1) at /usr/include/c++/5.3.0/ext/new_allocator.h:104
#8  0x0000000000401d9e in __gnu_cxx::__alloc_traits<std::allocator<Line> >::allocate (__a=..., __n=1) at /usr/include/c++/5.3.0/ext/alloc_traits.h:182
#9  0x0000000000401b90 in std::_Vector_base<Line, std::allocator<Line> >::_M_allocate (this=0x7fffffffe950, __n=1) at /usr/include/c++/5.3.0/bits/stl_vector.h:170
#10 0x0000000000401654 in std::vector<Line, std::allocator<Line> >::_M_insert_aux (this=0x7fffffffe950, __position=<error reading variable: Cannot access memory at address 0x0>, 
__x=...) at /usr/include/c++/5.3.0/bits/vector.tcc:353
#11 0x000000000040139e in std::vector<Line, std::allocator<Line> >::push_back (this=0x7fffffffe950, __x=...) at /usr/include/c++/5.3.0/bits/stl_vector.h:925
#12 0x0000000000400fff in Document::insertChar (this=0x7fffffffe9b0, chr=10 '\n') at Document.cpp:67
#13 0x00000000004011be in main (argc=1, argv=0x7fffffffeae8) at Document.cpp:204

简单介绍一下这个东西的设计,我用一个std::vector来保存线条(主要是为了方便)。还有类似于 Line 的类 向量,它是动态数组的实现。这样做的原因是我最终会在其中保存行元数据。

当我尝试使用 insert 插入 Line 时,Vector 似乎不喜欢它。 实际上,除了 Document::Document()。每当我尝试将 Line 对象插入向量中时,无论是 push_back 还是 insert。它失败了。

我...不太明白为什么,但很想。做不到这一点 - 我将不得不实现我自己的版本,所以我至少了解发生了什么。 (很遗憾,您在插入和搜索操作中无法获得 O(1)...如果我不需要快速搜索,那么链表会很好...)

【问题讨论】:

  • 请在您的问题中直接添加minimal reproducible example,而不是链接到其他网站上的大量代码。这里不是免费的调试服务。
  • 我试图复制这个问题但不能,所以我不能产生它。我会继续寻找隔离问题。就目前而言。我不知道是什么原因造成的。
  • std::vector 没有任何问题。可能有问题的是您的 Line 结构/类,因为它可能无法安全地复制或分配,这是向量需要的。
  • 我不是在责怪 std::vector。标准库是由比我优秀得多的程序员组合起来的。我知道问题几乎肯定出在 Line 上。我确实给出了一个基本的复制构造函数和赋值重载。两者都应该做一个适当的深拷贝。但是……显然不是。
  • 您应该在被放入向量之前对每个类进行单元测试以解决复制/分配问题。这可以通过编写一个简单的main 函数轻松完成,它所做的就是这样:ideone.com/4vGngSfoo 替换为您的类。如果main 显示任何问题,例如双重删除错误、内存泄漏等,请在您真正在 vector 中使用您的类之前修复它。

标签: c++ memory vector


【解决方案1】:

好的,睡了。回到这个。

delete [] mData 在复制构造函数中被调用。 mData 在复制构造函数的初始化列表中被初始化为 NULL。这就是问题 A。更重要的是;

std::copy(ln.mData, **mData**+mCapacity, mData);

不知道那时mData 的内存地址是什么。但这肯定不是本意。这是分配问题的根源。感谢指导我查看复制构造函数的人。

【讨论】:

    猜你喜欢
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2015-09-24
    相关资源
    最近更新 更多