当我将_Tp
类型的对象推回到std::vector
时,会出现一个段错误信号SIGSEGV
,其中template new_allocator<_Tp>
会在以下代码段的末尾返回:
pointer
allocate(size_type __n, const void* = 0)
{
if (__n > this->max_size())
std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); /* SEGMENT FAULT! */
}
对以下表达式的持续监控产生
(this->max_size()) = 1343857
(__n) = 4
(sizeof(_Tp)) = 3196
__n * sizeof(_Tp) = 12784
我可以说内存显然已经足够,并且所有寄存器都很好。
然而,这个段错误DID不会发生,直到推了几次,因为我认为向量最初足够大,可以在没有::operator new
的情况下推进到那一刻。但无论什么时候必须return static_cast<_Tp *>(::operator new(__n * sizeof(_Tp)))
,都会发生不好的事情。
尽管如此,关于_Tp
的一个事实是它确实是一个没有DEFAULT CONSTRUCTOR的类实现,因为它有一些引用类型的成员字段,并且不能默认构造。就static_cast<_Tp *>
和operator new
的语义而言(全局原始,在我的代码中没有被覆盖),这可能与段错误有关吗?我是否应该为自己实现_Tp类型的分配器而烦恼,还是有别的办法?谢谢。
使用
Ubuntu 12.04 x86-64, GCC 4.6.3, IDE Netbeans 7.4, std=C++98
答案 0 :(得分:3)
在这种情况下,allocate
函数只是分配内存 - 它还没有在该位置构造一个对象。它调用全局运算符new - 而不是类型的构造函数。然后,它将使用placement new在生成的内存块中构造对象。
如果您在这里遇到分段错误,则意味着您的内存不足,或者您的程序已损坏堆。损坏堆会导致未定义的行为,并且通常会在程序中远离您损坏它的位置崩溃。可能这里最常见的原因是在释放后使用内存;至少在使用free
'd空间来跟踪分配的系统上(例如dlmalloc
,最常见的* nix分配器)。另一个常见原因是尝试注销先前由分配器处理的缓冲区的结尾。
您可以考虑在valgrind
下运行此程序。