Jump to content
  • Advertisement
Sign in to follow this  
Evil Steve

Override Placement New?

This topic is 4029 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

Hi all, I'm in the process of writing a memory manager, and I've run into a problem. I'm trying to use placement new like so:
void* pBuff = malloc(sizeof(PMemory));
PMemory* pMemory = ::new(pBuff) PMemory();



However, that gives me:
Quote:
pmemory.cpp(82) : error C2660: 'operator new' : function does not take 2 arguments
I've overridden the global operator new (and new[], delete and delete[]), but that's in another source file, so the compiler shouldn't be aware of it at all... Does anyone have any ideas what the hell's going on? Do I need to somehow override placement new as well? EDIT: The following project also causes the same problem. Am I just screwing up the syntax for placement new or something?
#include "malloc.h"

class PMemory
{
public:
	PMemory() {}
	~PMemory() {}
};


int main(int argc, char** argv[])
{
	void* pBuff = malloc(sizeof(PMemory));
	PMemory* pMemory = new(pBuff) PMemory();
	return 0;
}

Cheers, Steve

Share this post


Link to post
Share on other sites
Advertisement
void* pBuff = malloc(sizeof(PMemory));
PMemory* pMemory = ::new(pBuff) PMemory();


This looks very strange. Why are you trying to mix malloc and new? Mixing them is evil, you know.

Maybe this will work better:
void* pBuff = new char[sizeof(PMemory)];
PMemory* pMemory = ::new(pBuff)PMemory();

Or, safer code:
char mem[sizeof(PMemory)];
void* pBuff = mem;
PMemory* pMemory = ::new(pBuff)PMemory();

Share this post


Link to post
Share on other sites
Yeah, I'm aware of the problems with mixing new and malloc(). I have my reasons though [smile]

This is a memory manager, so obviously I can't call new (It would invoke the memory manager, which means an infinite loop then stack overflow), and I need to reference the object outside of the function, so an array isn't any good either. A static array would be ok, but that gives the same problem:

static char pBuff[sizeof(PMemory)];
PMemory* pMemory = new(pBuff) PMemory();


Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
You must include new (#include <new>) to use placement new.
Hooray!

Thanks [smile]

Share this post


Link to post
Share on other sites
This is the way I have done this in the past, it makes it much nicer to just create using new. Obviously this is a trimmed down version which has problems yet it shows what it is meant to.


#include <stdexcept>

struct Bar
{
Bar():bar(0){}
int bar;
};
struct Mem_manger
{
static Mem_manger* ptr()//ye ye a singleton just to make it nice and easy for the example
{
static Mem_manger* m_this(0);
if(!m_this)
{
m_this = new Mem_manger;
}
return m_this;
}
void* memory(size_t size)
{
//here you should see if you have a slot the correct size of bigger
//attach your header for slot
//remove the slot from the list etc
return m_buffer;
}
static void * operator new( size_t size )
{
return malloc( size );
}

static void operator delete( void * memory )
{
if ( !memory )
return;

free( memory );
}

private:
Mem_manger(){}
char m_buffer[sizeof(Bar)];//temp should get it from a buffer which is managed

};

void * operator new( size_t size, Mem_manger * heap )
{
return heap->memory(size);
}

void * operator new( size_t size )
{
void* ptr = operator new( size, Mem_manger::ptr() );
if(!ptr)throw std::bad_alloc("could not get the memory");
return ptr;
}


int main(int argc, char *argv[])
{

Bar* b = new Bar;

return 0;
}


Share this post


Link to post
Share on other sites
Original post by Hnefi

Or, safer code:
char mem[sizeof(PMemory)];
void* pBuff = mem;
PMemory* pMemory = ::new(pBuff)PMemory();


Safer? It looks like a textbook example of brutal stack smashing: if "pMemory" is copied back to the caller, the stack allocated "mem" goes out of scope and the object overlaps with arbitrary subsequent stack frames.
An allocated buffer, at worst, can only be leaked.
The only safe thing about this variant is that allocation "cannot fail" (unless the stack overflows, of course), but checking the result of malloc or operator new is more practical.

Share this post


Link to post
Share on other sites
Obviously, if the memory was to be used outside of the function in which it was called, it would have to be static. And obviously, it would have to be of limited size to prevent stack problems.

I assumed (correctly, I believe) that these are issues that the OP is competent enough to recognize on his own, without me having to go over every ramification of the method in detail.

Share this post


Link to post
Share on other sites
Unfortunately, neither the static or stack based char array guarantees proper alignment, which means the placement new might die a messy death by SIGBUS or its moral equivalent for the platform the code gets run on.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Unfortunately, neither the static or stack based char array guarantees proper alignment, which means the placement new might die a messy death by SIGBUS or its moral equivalent for the platform the code gets run on.


You could overallocate by (alignment size - 1) bytes and then round up?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!