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

问题描述 投票:0回答:2

当我将

_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

我可以看出内存显然是足够的,并且所有寄存器都很好。

但是,这个段错误直到推送几次后才发生,因为我认为向量最初足够大,可以在没有

::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
c++ vector stl
2个回答
4
投票

本例中的

allocate
函数只是分配内存——它尚未在该位置构造对象。它正在调用全局运算符 new - 而不是您类型的构造函数。然后它将使用placement new 在生成的内存块中构造您的对象。

如果您在这里遇到分段错误,则意味着您的内存不足,或者您的程序已损坏堆。损坏堆会导致未定义的行为,并且通常会在程序中远离损坏位置的地方崩溃。这里最常见的原因可能是释放内存后使用内存;至少在使用

free
空间来跟踪分配的系统上(例如
dlmalloc
,最常见的 *nix 分配器)。另一个常见原因是尝试注销之前分配器交给您的缓冲区的末尾。

您可能希望考虑在

valgrind
下运行此程序。


0
投票

嗯,我今天就遇到了这个。事实证明这是一个真正的STACKOVERFLOW。 🗿

© www.soinside.com 2019 - 2024. All rights reserved.