std :: vector函数push_back中的奇怪段错误

时间:2014-01-16 04:57:38

标签: c++ vector stl

当我将_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

1 个答案:

答案 0 :(得分:3)

在这种情况下,allocate函数只是分配内存 - 它还没有在该位置构造一个对象。它调用全局运算符new - 而不是类型的构造函数。然后,它将使用placement new在生成的内存块中构造对象。

如果您在这里遇到分段错误,则意味着您的内存不足,或者您的程序已损坏堆。损坏堆会导致未定义的行为,并且通常会在程序中远离您损坏它的位置崩溃。可能这里最常见的原因是在释放后使用内存;至少在使用free'd空间来跟踪分配的系统上(例如dlmalloc,最常见的* nix分配器)。另一个常见原因是尝试注销先前由分配器处理的缓冲区的结尾。

您可以考虑在valgrind下运行此程序。