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

我可以说内存显然足够了,所有寄存器都很好。

然而,这个段错误直到推送几次才发生,因为我认为 vector 最初足够大,可以在没有 ::operator new 的情况下推送直到那一刻。但是每当它必须 return static_cast<_Tp *>(::operator new(__n * sizeof(_Tp))) 时,坏事就会发生。

尽管如此,关于 _Tp 的一个事实是,它确实是一个没有默认构造函数的类实现,因为它具有某些引用类型的成员字段,并且不能默认构造。就 static_cast<_Tp *>operator new 的语义而言(全局原创,未在我的代码中覆盖),这可能与段错误有关吗?我是否应该为自己实现 _Tp 类型的分配器而烦恼,还是有其他方法?谢谢。


Ubuntu 12.04 x86-64, GCC 4.6.3, IDE Netbeans 7.4, std=C++98

最佳答案

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

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

您可能希望考虑在 valgrind 下运行此程序。

关于c++ - std::vector 函数 push_back 中的奇怪段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21153636/

10-13 08:09
查看更多