Search code examples
c++vectorstl

Weird segment fault in function push_back of std::vector


When I push object of type _Tp back into std::vector, a segment fault signal SIGSEGV arises where template new_allocator<_Tp> returns around the end of following snippet:

  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! */
  }

Constant monitoring about following expressions yields

(this->max_size()) = 1343857
(__n) = 4
(sizeof(_Tp)) = 3196
__n * sizeof(_Tp) = 12784

I can tell that the memory is apparently enough and all registers are fine.

However, this segment fault DID NOT occur until pushing for a few times, as I think the vector is initially large enough to push without ::operator new until the moment. But whenever it has to return static_cast<_Tp *>(::operator new(__n * sizeof(_Tp))), bad thing just happens.

Despite that, one fact about _Tp is that it's indeed a class implementation WITHOUT DEFAULT CONSTRUCTOR, as it has member field of some a reference type and must not be constructed by default. In terms of the semantics of static_cast<_Tp *> and operator new (globally original, not overwritten in my code), is this possibly relevant to the segment fault? Should I be troubled to implement an allocator of type _Tp myself or is there other way around? Thanks.

With

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

Solution

  • The allocate function in this case is just allocating memory -- it has not yet constructed an object at that location. It is calling global operator new -- not your type's constructor. It will then use placement new to construct your objects in the resulting memory block.

    If you are getting segmentation faults here, it either means that you are out of memory, or that your program has corrupted the heap. Corrupting the heap causes undefined behavior, and will often crash far away in your program from where you corrupted it. Probably the most common cause here would be using the memory after freeing it; at least on systems which use free'd space to track allocations (e.g. dlmalloc, the most common *nix allocator). Another common cause would be attempting to write off the end of a buffer you were handed by an allocator previously.

    You may wish to consider running this program under valgrind.