Archived

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

mishikel

Placement New

Recommended Posts

Using Borland CBuilder 5, I'm trying to place a dynamically allocated array into shared memory using placement new. However, the compiler can't seem to resolve int* array = new(sharedMemoryLocation) int[sizeOfArray]; since in new.h, no operator of form: inline void* operator new[] (size_t, void* p) is defined. I've therefore defined my own placement new as: inline void* operator new[] (size_t, void* p) { return p; } And everything "seems" to work fine. My questions are. 1. For BCB5, why isn't there placement new for arrays? MSVC .NET seems to define this operator. 2. Due to the nature of placement new, is the above code a valid implementation? Matt [edited by - mishikel on January 22, 2004 11:18:55 AM] [edited by - mishikel on January 22, 2004 11:19:57 AM]

Share this post


Link to post
Share on other sites
Funny that you haven''t got a placement new....still:
Your placement new is fine - same as a "proper" implementation.
You can''t have placement new for array - MSVC 2003 .NET doesn''t support it - C++ doesn''t support it currently.
You have to placement new each array element seperately - no real biggy though.
Remember not to call delete on the memory though - judging by your post you''re not going to, but just being sure.

Share this post


Link to post
Share on other sites
How exactly is it useless? I need an array of elements, each element constructed and placed at a memory location offset by the size of the element type, starting at an address I specify.

Do you mean useless in the sense that the body of the operators are exactly the same?

Share this post


Link to post
Share on other sites
It''s useless for a number of reasons. One is that there''s no standards complaint way of knowing how much memory you need to allocate before hand. Another is that there''s no reliable orthogonal way to destroy the objects afterwards.

Basically the standard doesn''t guarantee that the memory address you give it will be the same as the memory address the new expression returns, which can lead to wonderfully annoying cases of heap corruption.

Instead of using placement array new, you should consider using std::allocator''s functionality or perhaps std::uninitialized_fill().

Share this post


Link to post
Share on other sites
Your placement operator new[] is almost ok. According to the standard it should have a throw() specification too (i.e. shouldnt throw anything).

Its usually a good idea to define operator delete[] for each operator new[] you define, which in this case, the standard says should be of the form:

void operator delete[](void* ptr, void*) throw();

Which should perform no actions.

Share this post


Link to post
Share on other sites
Thanks for the answers, guys. I forgot about the no throw specification. As for overloading operator placement delete[], I thought that, when using placement new, I am responsible for invoking any destructors manually, as in:


// Allocate the memory.
char* buffer = new char[sizeof(Object)];
void* address = buffer;

// Construct an object at the specified memory location.
Object* obj = new(address) Object();

// Manually destroy the object.
obj->~Object();

// Free the memory.
delete[] buffer;


I thought that there wasn''t any valid placement delete. (http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10) This is a pretty tricky subject.

I''m cutting some corners, however, since I''m constructing an array of an integral type, so it doesn''t need to have its destructor invoked. And the memory allocation is handled with the shared memory ::CreateFileMapping/::MapViewOfFile and deallocation with ::UnmapViewOfFile/::CloseHandle. At least I hope it is.

Has anyone done something like this before?



Matt

Share this post


Link to post
Share on other sites
Placement delete is called by the compiler if the constructor in a placement new expression throws. Otherwise it''s not used.

If you''re just using the memory as an array of integral type, just cast the darn pointer and be done with it. Don''t bother with placement array new.

Share this post


Link to post
Share on other sites
The problem with placement new[] is the (idiotic) failure to lift the restriction that new[] can allocate an implementation-defined amount of extra memory. The result is that if you want to construct a load of objects into existing memory with placement new[] you don''t know how much memory to allocate in the array, because you don''t know how much will be consumed by the implementation.

But since destroying the objects placement new[]-ed into place is your responsibility (not the compiler''s), and since no memory bookkeeping needs to be done (because placement new[] doesn''t allocate memory) there''s no good reason (AFAIK) for allowing this overallocation.

Share this post


Link to post
Share on other sites