Archived

This topic is now archived and is closed to further replies.

Choosing class Allocator or New

This topic is 5045 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''ve read before that using the
new
operator to dynamically allocate memory will always call
T::T()
and that one option to get around that is to use
allocator<T>
from the memory header so that it can reserve raw memory that would be uninitialized until it is needed. One purpose behind using uninitialized storage is in reserving a chunk of memory for say a vector class where the design can dictate memory growing by more than would be needed for just a single push_back (cutting down overhead). Regardless of the reason or point, I was wondering whether there is really any way to use the new operator to not attempt to initialize elements of type T in an array or another method that doesn''t use allocator, or perhaps I should stick with allocator in these situations?

Share this post


Link to post
Share on other sites
In MSVC++, the STL allocator gets its uninitialized memory by directly invoking operator new. Keep in mind that when you use the "new" keyword, TWO things happen: the compiler invokes the appropriate operator new, and then it invokes the constructor. So if you were to do something like this:
MyClass* myClass = (MyClass*)operator new(sizeof(MyClass));
you'd get a block of the appropriate size without causing the constructor to fire.


"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on February 20, 2004 10:47:03 PM]

Share this post


Link to post
Share on other sites
You can use the untyped global operator new to allocate memory without calling a constructor. It returns a void * so you need to do some type casting in order to use it. e.g.:

void * ptr = ::operator new(sizeof(T));
T * pT = reinterpret_cast<T *>(ptr);


However, it''s usually not a good idea to use this kind of code unless you know exactly what you''re doing.

Oh, and you can always fall back on malloc()/free().

Share this post


Link to post
Share on other sites
You can allocate memory however you want. However, casting uninitialized memory to a class type will not work right if that class has virtual members or bases, because the vtable slot is not properly initialized.

To get around this, there is "placement new" and "placement delete". Typically, you''ll do something like:


char * block = (char *)malloc( 10 * sizeof( T ) );
char * cur = block;

T * make_one() {
//fixme: handle overflow, etc here
void * ret = cur;
ret += sizeof( T );
return new(ret) T();
}

void delete_one( T * t ) {
t->~T();
put_on_free_list( t );
}


Note that calling delete on something allocated with placement new IS AN ERROR. You have to destroy it with placement destruction, and handle the memory separately.

Share this post


Link to post
Share on other sites
Thanks guys, I found all three of your posts to be helpful and will give me something to play with.

[edited by - nervo on February 21, 2004 3:36:38 AM]

Share this post


Link to post
Share on other sites
I''m wondering are there any reference sites available that explains some of the more arcane uses of new/delete and some of it''s possible applications? I''m thinking something that''s like function-pointer.org

Thanks





--{You fight like a dairy farmer!}

Share this post


Link to post
Share on other sites