Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Custom STL in place allocator crashed

Reply
Thread Tools

Custom STL in place allocator crashed

 
 
Allen
Guest
Posts: n/a
 
      12-31-2008
There is a custom STL in place allocator in Google codes.
The InPlaceAlloc.h URL is
http://www.google.com/codesearch/p?h...InPlaceAlloc.h

#include <vector>
#include "InPlaceAlloc.h"

int main()
{
char * buffer = new char[1024];
typedef InPlaceAlloc<int> IPA;
std::vector<int, IPA> v(IPA(buffer, 1024));

// insert elements
// - causes reallocations
v.push_back(42);
v.push_back(56);
v.push_back(11);
v.push_back(22);
v.push_back(33);
v.push_back(44);

delete[] buffer;
buffer = NULL;
}

Run the program in MSVC8, it will crash.

Why? Please help me. Thank you.

Allen
 
Reply With Quote
 
 
 
 
red floyd
Guest
Posts: n/a
 
      12-31-2008
Allen wrote:
> There is a custom STL in place allocator in Google codes.
> The InPlaceAlloc.h URL is
> http://www.google.com/codesearch/p?h...InPlaceAlloc.h
>
> #include <vector>
> #include "InPlaceAlloc.h"
>
> int main()
> {
> char * buffer = new char[1024];
> typedef InPlaceAlloc<int> IPA;
> std::vector<int, IPA> v(IPA(buffer, 1024));
>
> // insert elements
> // - causes reallocations
> v.push_back(42);
> v.push_back(56);
> v.push_back(11);
> v.push_back(22);
> v.push_back(33);
> v.push_back(44);
>
> delete[] buffer;
> buffer = NULL;

At this point, v's destructor has yet to run.
> }
>
> Run the program in MSVC8, it will crash.
>
> Why? Please help me. Thank you.
>

 
Reply With Quote
 
 
 
 
Allen
Guest
Posts: n/a
 
      12-31-2008
On 12月31日, 上午9时14分, Allen <Allen.Che...@gmail..com> wrote:
> There is a custom STL in place allocator in Google codes.
> The InPlaceAlloc.h URL ishttp://www.google.com/codesearch/p?hl=en#HClD5fLW7P8/InPlaceAlloc.h&q...
>
> #include <vector>
> #include "InPlaceAlloc.h"
>
> int main()
> {
> char * buffer = new char[1024];
> typedef InPlaceAlloc<int> IPA;
> std::vector<int, IPA> v(IPA(buffer, 1024));


It crashs at above line.

>
> // insert elements
> // - causes reallocations
> v.push_back(42);
> v.push_back(56);
> v.push_back(11);
> v.push_back(22);
> v.push_back(33);
> v.push_back(44);
>
> delete[] buffer;
> buffer = NULL;
>
> }
>
> Run the program in MSVC8, it will crash.
>
> Why? Please help me. Thank you.
>
> Allen


 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      12-31-2008
Allen schrieb:
> On 12月31日, 上午9时14分, Allen <(E-Mail Removed)> wrote:
>> There is a custom STL in place allocator in Google codes.
>> The InPlaceAlloc.h URL ishttp://www.google.com/codesearch/p?hl=en#HClD5fLW7P8/InPlaceAlloc.h&q...
>>
>> #include <vector>
>> #include "InPlaceAlloc.h"
>>
>> int main()
>> {
>> char * buffer = new char[1024];


Avoid new[]. Avoid delete[]. Except buried down in a class or library.
You can use std::vector to allocate a buffer:

std::vector<char> buffer(1024);

>> typedef InPlaceAlloc<int> IPA;
>> std::vector<int, IPA> v(IPA(buffer, 1024));


std::vector<int, IPA> v(IPA(&buffer[0], buffer.size()));

> It crashs at above line.


It crashs, because InPlaceAlloc is broken. The copy constructor and the
assignment operator are defined but empty with a comment saying "do
nothing". That won't work.

--
Thomas
 
Reply With Quote
 
tni
Guest
Posts: n/a
 
      12-31-2008
Allen wrote:
> There is a custom STL in place allocator in Google codes.
> The InPlaceAlloc.h URL is
> http://www.google.com/codesearch/p?h...InPlaceAlloc.h
>
> #include <vector>
> #include "InPlaceAlloc.h"
>
> int main()
> {
> char * buffer = new char[1024];
> typedef InPlaceAlloc<int> IPA;
> std::vector<int, IPA> v(IPA(buffer, 1024));



You do realize that you are using an int vector with a char sized
buffer, right?

It should be:
char * buffer = new char[1024 * sizeof(int)];
 
Reply With Quote
 
zr
Guest
Posts: n/a
 
      12-31-2008
On Dec 31, 4:20 am, "Thomas J. Gritzan" <(E-Mail Removed)>
wrote:
> Allen schrieb:
>
> > On 12月31日, 上午9时14分, Allen <(E-Mail Removed)> wrote:
> >> There is a custom STL in place allocator in Google codes.
> >> The InPlaceAlloc.h URL ishttp://www.google.com/codesearch/p?hl=en#HClD5fLW7P8/InPlaceAlloc.h&q...

>
> >> #include <vector>
> >> #include "InPlaceAlloc.h"

>
> >> int main()
> >> {
> >> char * buffer = new char[1024];

>
> Avoid new[]. Avoid delete[]. Except buried down in a class or library.
> You can use std::vector to allocate a buffer:
>
> std::vector<char> buffer(1024);
>

Why is using a vector to allocate better than using new[] and delete
[]?
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      12-31-2008
zr wrote:
> Why is using a vector to allocate better than using new[] and delete
> []?


Because a std::vector is scoped, which means that when it goes out of
scope, it will delete the array automatically, thus lessening the
chances of a memory leak (especially inside functions which may have
surprising exit points).

Basically std::vector is an encapsulated way of dynamically allocating
an array.

When you write a 'new' and use the raw pointer, you always risk a
memory leak if you are not very careful.
 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      12-31-2008
zr schrieb:
> On Dec 31, 4:20 am, "Thomas J. Gritzan" <(E-Mail Removed)>
> wrote:
>> Allen schrieb:
>>
>>> On 12月31日, 上午9时14分, Allen <(E-Mail Removed)> wrote:
>>>> There is a custom STL in place allocator in Google codes.
>>>> The InPlaceAlloc.h URL ishttp://www.google.com/codesearch/p?hl=en#HClD5fLW7P8/InPlaceAlloc.h&q...
>>>> #include <vector>
>>>> #include "InPlaceAlloc.h"
>>>> int main()
>>>> {
>>>> char * buffer = new char[1024];

>> Avoid new[]. Avoid delete[]. Except buried down in a class or library.
>> You can use std::vector to allocate a buffer:
>>
>> std::vector<char> buffer(1024);
>>

> Why is using a vector to allocate better than using new[] and delete
> []?


In general, because it lessens the risk of memory leaks.
With new[], you have to delete[] in every possible code path, which can
be quite complicated in some functions, especially if you allocate
multiple arrays.
It is very hard to make it exception safe. Most people don't even try it
and ignore that issue. With std::vector or any other smart-pointer or
RAII construct, the objects will be destroyed even then.

In this special case, the buffer is used by the other std::vector and
its allocator. The code delete[]s the buffer to early while it is still
in use. But destructors run in reverse order to its constructor calls,
so if you use std::vector in this case, the buffer won't be deallocated
until the vector that uses this buffer is alive.

--
Thomas
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      01-01-2009
On Dec 31 2008, 4:04 pm, Pete Becker <(E-Mail Removed)> wrote:
> On 2008-12-31 09:37:54 -0500, zr <(E-Mail Removed)> said:
> > On Dec 31, 4:20 am, "Thomas J. Gritzan" <(E-Mail Removed)>
> > wrote:
> >> Allen schrieb:


> >>> On 12鏈31鏃, 涓婂崍9鏃14鍒, Allen <Allen.Che...@g

> > mail.com> wrote:
> >>>> There is a custom STL in place allocator in Google codes.
> >>>> The InPlaceAlloc.h URL ishttp://www.google.com/codesearch/p?hl=en#HC

> > lD5fLW7P8/InPlaceAlloc.h&q...


> >>>> #include <vector>
> >>>> #include "InPlaceAlloc.h"


> >>>> int main()
> >>>> {
> >>>> char * buffer = new char[1024];


> >> Avoid new[]. Avoid delete[]. Except buried down in a class or library.
> >> You can use std::vector to allocate a buffer:


> >> std::vector<char> buffer(1024);


> > Why is using a vector to allocate better than using new[] and delete
> > []?


> Orthodoxy.


In the usual case where the lifetime is scoped, it's the
simplest way to ensure exception safety, and definitly to be
prefered. Any time the array is to be passed as a parameter, it
acts like a real type, with value semantics and no special ad
hoc rules about converting to a pointer to the first element,
and it carries its size around with it as well. Most
implementations will also bounds check, which is really, really
rare for built in arrays. (I think I've only heard of one
compiler which bounds checks built-in arrays, and I don't know
if it is even still around.)

In 20 years of programming C++, I've never used an operator
new[]. (I do still use C style arrays in certain cases, but
never dynamically allocated.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orient茅e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S茅mard, 78210 St.-Cyr-l'脡cole, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      01-01-2009
On Dec 31 2008, 8:42 pm, "Thomas J. Gritzan" <(E-Mail Removed)>
wrote:
> zr schrieb:
> > On Dec 31, 4:20 am, "Thomas J. Gritzan" <(E-Mail Removed)>
> > wrote:
> >> Allen schrieb:


> >>> On 12鏈31鏃, 涓婂崍9鏃14鍒, Allen <(E-Mail Removed)> wrote:
> >>>> There is a custom STL in place allocator in Google codes.
> >>>> The InPlaceAlloc.h URL ishttp://www.google.com/codesearch/p?hl=en#HClD5fLW7P8/InPlaceAlloc.h&q...
> >>>> #include <vector>
> >>>> #include "InPlaceAlloc.h"
> >>>> int main()
> >>>> {
> >>>> char * buffer = new char[1024];
> >> Avoid new[]. Avoid delete[]. Except buried down in a class or library.
> >> You can use std::vector to allocate a buffer:


> >> std::vector<char> buffer(1024);


> > Why is using a vector to allocate better than using new[]
> > and delete []?


> In general, because it lessens the risk of memory leaks. With
> new[], you have to delete[] in every possible code path, which
> can be quite complicated in some functions, especially if you
> allocate multiple arrays. It is very hard to make it
> exception safe. Most people don't even try it and ignore that
> issue. With std::vector or any other smart-pointer or RAII
> construct, the objects will be destroyed even then.


That's true, but not really relevant here. Similarly, a much
more important reason for using std::vector is that in any
decent implementation, the operator[] will be bounds checked,
and the type in general behaves like a normal type, with value
semantics. And that the type carries its dimensions along with
it.

None of which are really relevant here, because the user isn't
allocating an array, in the classical sense, he's allocating raw
memory. And the problem with new char[] is that it says the
wrong thing; it says that he is allocating an array of char. I
know, the language allows an array of char to be used as raw
memory. But that doesn't mean that you can't write code which
says what you mean. In this case, I'd call the :perator new
function directly, e.g.:

void* buffer = :perator new( quantityNeeded ) ;
// ...
:perator delete( buffer ) ;

(I'd also maintain the pointer as a void* where ever possible,
since this is the conventional type for a pointer to raw
memory.)

With regards to his original code:

1. I'd also ensure that the allocator took not only a pointer,
but also the size, and verify that constantly. (Part of his
problem, at least, is that the array he's allocating isn't
big enough.)

2. I'd define some memory management strategy. The simplest,
here, is just to use the Boehm collector; another solution
I've found useful in many cases is to pass an additional
boolean argument to the client, telling it whether to delete
in the destructor or not---since allocator must support
copy, this would require some tricky reference counting
here. Or... Just a guess, but it wouldn't surprise me if in
all of the actual use cases for this class, the memory
doesn't really have to be deleted anyway. (But if he'd
posted code without the delete, a lot of people would have
screamed about that.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orient茅e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S茅mard, 78210 St.-Cyr-l'脡cole, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
STL custom allocator design Dave Rahardja C++ 4 02-01-2007 04:48 AM
Idea for custom thread-safe STL allocator? Brian Genisio C++ 12 01-15-2004 03:41 PM
Nero Crashed and Burned (Well, not exactly - just crashed) Dave Watson Computer Support 12 11-19-2003 11:40 PM
How to write an allocator for the STL List in VC++ 6.0 =?ISO-8859-1?Q?Ralf_Schneewei=DF?= C++ 2 08-20-2003 11:48 PM
[ANN] Thread-aware STL-compatible memory allocator Dan C++ 0 07-29-2003 08:06 PM



Advertisments