2014-01-16 89 views
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 

我可以告诉内存显然是足够的,所有寄存器都很好。

但是,这个段的故障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

这是你在那里的一个巨大的类,但没有默认的构造函数会在编译时出现问题。 – chris

回答

3

allocate功能在这种情况下,刚刚分配内存 - 还没有建造在该位置的对象。它调用全局运算符new - 而不是您类型的构造函数。然后,它将使用placement new来在结果内存块中构造对象。

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

你不妨考虑在valgrind下运行这个程序。

+0

尽管如此,“placement new”如何与没有默认构造函数或重载的new运算符的类一起使用? –

+0

你显示的片段只是分配原始内存。向矢量添加元素将执行新的位置以调用复制构造函数。 –

+0

不应该在内存不足的情况下抛出异常? – UldisK