Behaviour of custom allocator for vector

A

Alex Vinokur

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)
 
R

richard

Alex said:
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.
 
A

Alex Vinokur

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
 
K

Kai-Uwe Bux

Alex said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top