Behaviour of custom allocator for vector

Discussion in 'C++' started by Alex Vinokur, Apr 1, 2006.

  1. Alex Vinokur

    Alex Vinokur Guest

    Compiler GNU g++ version 3.4.4 (cygming special)

    Custom allocator for vector (see below) checks a return value of
    'operator new'.
    If that value is NULL, the allocator "allocates" no memory.
    Nevertheless the allocator produces "Segmentation fault (core dumped)".
    Is it possible to correct that allocator in order to avoid such
    behavior

    ------ foo.cpp ------
    #include <vector>
    #include <cstddef>
    #include <iostream>
    using namespace std;

    template <class T> class my_alloc
    {
    public:
    typedef T value_type;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;

    pointer allocate(size_type sz, void* vp = 0)
    {
    pointer p = static_cast<pointer>(operator new (sz *
    sizeof(value_type), nothrow));
    if (p == 0)
    {
    cerr << "[1] Unable to alloc: size = " << sz << endl;
    p = static_cast<pointer>(operator new (0 * sizeof(value_type),
    nothrow));
    if (p == 0)
    {
    cerr << "[2] Unable to alloc: size = 0" << endl;
    }
    else
    {
    cerr << "[3] Alloc: size = 0" << endl;
    }
    }

    return p;
    }

    void deallocate(pointer p, size_type)
    {
    if (p == 0)
    {
    cerr << "[4] Unable to dealloc" << endl;
    return;
    }
    cerr << "[5] Dealloc" << endl;
    operator delete(p, nothrow);
    }
    };

    int main()
    {
    vector<int, my_alloc<int> > v (0xfffffffe);

    return 0;

    }

    ---------------------


    ------ Run ---

    [1] Unable to alloc: size = 4294967294
    [3] Alloc: size = 0
    Segmentation fault (core dumped)

    --------------


    --
    Alex Vinokur
    email: alex DOT vinokur AT gmail DOT com
    http://mathforum.org/library/view/10978.html
    http://sourceforge.net/users/alexvn
     
    Alex Vinokur, Apr 1, 2006
    #1
    1. Advertising

  2. Alex Vinokur

    Guest

    Alex Vinokur wrote:
    > Compiler GNU g++ version 3.4.4 (cygming special)
    >
    > Custom allocator for vector (see below) checks a return value of
    > 'operator new'.
    > If that value is NULL, the allocator "allocates" no memory.
    > Nevertheless the allocator produces "Segmentation fault (core dumped)".


    You should throw a bad_alloc exception rather than returning NULL from
    the allocate() function. You may as well allow ::eek:perator new() to
    throw bad_alloc (it could contain useful debugging information --
    though in gcc 3.4.4 I think it doesn't) and catch, log and rethrow in
    that event.

    --
    Richard Smith
     
    , Apr 1, 2006
    #2
    1. Advertising

  3. Alex Vinokur

    Alex Vinokur Guest

    wrote:
    > Alex Vinokur wrote:
    > > Compiler GNU g++ version 3.4.4 (cygming special)
    > >
    > > Custom allocator for vector (see below) checks a return value of
    > > 'operator new'.
    > > If that value is NULL, the allocator "allocates" no memory.
    > > Nevertheless the allocator produces "Segmentation fault (core dumped)".

    >
    > You should throw a bad_alloc exception rather than returning NULL from
    > the allocate() function. You may as well allow ::eek:perator new() to
    > throw bad_alloc (it could contain useful debugging information --
    > though in gcc 3.4.4 I think it doesn't) and catch, log and rethrow in
    > that event.

    [snip]

    I use nothrow in 'operator new", I want to avoid exception handling.

    Alex Vinokur
    email: alex DOT vinokur AT gmail DOT com
    http://mathforum.org/library/view/10978.html
    http://sourceforge.net/users/alexvn
     
    Alex Vinokur, Apr 1, 2006
    #3
  4. Alex Vinokur

    Kai-Uwe Bux Guest

    Alex Vinokur wrote:

    > Compiler GNU g++ version 3.4.4 (cygming special)
    >
    > Custom allocator for vector (see below) checks a return value of
    > 'operator new'.
    > If that value is NULL, the allocator "allocates" no memory.
    > Nevertheless the allocator produces "Segmentation fault (core dumped)".
    > Is it possible to correct that allocator in order to avoid such
    > behavior


    Yes: use exceptions.


    > ------ foo.cpp ------
    > #include <vector>
    > #include <cstddef>
    > #include <iostream>
    > using namespace std;
    >
    > template <class T> class my_alloc
    > {
    > public:
    > typedef T value_type;
    > typedef size_t size_type;
    > typedef ptrdiff_t difference_type;
    > typedef T* pointer;
    > typedef const T* const_pointer;
    > typedef T& reference;
    > typedef const T& const_reference;
    >
    > pointer allocate(size_type sz, void* vp = 0)
    > {
    > pointer p = static_cast<pointer>(operator new (sz *
    > sizeof(value_type), nothrow));
    > if (p == 0)
    > {
    > cerr << "[1] Unable to alloc: size = " << sz << endl;
    > p = static_cast<pointer>(operator new (0 * sizeof(value_type),
    > nothrow));
    > if (p == 0)
    > {
    > cerr << "[2] Unable to alloc: size = 0" << endl;
    > }
    > else
    > {
    > cerr << "[3] Alloc: size = 0" << endl;
    > }
    > }
    >
    > return p;
    > }
    >
    > void deallocate(pointer p, size_type)
    > {
    > if (p == 0)
    > {
    > cerr << "[4] Unable to dealloc" << endl;
    > return;
    > }
    > cerr << "[5] Dealloc" << endl;
    > operator delete(p, nothrow);
    > }
    > };
    >
    > int main()
    > {
    > vector<int, my_alloc<int> > v (0xfffffffe);
    >
    > return 0;
    >
    > }
    >
    > ---------------------
    >
    >
    > ------ Run ---
    >
    > [1] Unable to alloc: size = 4294967294
    > [3] Alloc: size = 0
    > Segmentation fault (core dumped)


    It is not the allocator that produces the segfault. However, your allocator
    does not keep the contract that an allocator is required to obey. What
    happens is that vector assumes the returned pointer to be valid and tries
    to construct and object in that place. This causes the segfault. There is
    no way around that. The containers work with allocators in such a way that
    error handling is done by throwing exceptions. There are no hooks into
    std::vector that allow for a different method of error handling.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Apr 1, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gernot Frisch

    std::vector allocator?

    Gernot Frisch, Jul 21, 2004, in forum: C++
    Replies:
    4
    Views:
    3,268
    Gernot Frisch
    Jul 21, 2004
  2. Alex Vinokur
    Replies:
    16
    Views:
    12,333
    Alex Vinokur
    Aug 16, 2004
  3. Replies:
    8
    Views:
    1,960
    Csaba
    Feb 18, 2006
  4. Replies:
    3
    Views:
    3,119
  5. z65536
    Replies:
    4
    Views:
    439
    red floyd
    Jul 6, 2010
Loading...

Share This Page