Gokul
Gokul

Reputation: 933

Operator new overloading in windows

I am trying to replace the global operator new and delete. In Linux this works fine, but in windows( MSVC 10 ), it sometimes allocates using the system version of operator new and then tries to deallocate it using my operator delete. Since i am storing some context information while allocation, my operator delete expects the same during deallocation. How would i make sure that the windows picks up my operator new at all times?

edit: I have tried various stuffs. These are the declaration

//Global new and delete overload
void* operator new (std::size_t bytes) throw(...);
void operator delete(void* p) throw();

void* operator new( std::size_t size, const std::nothrow_t&) throw();
void operator delete( void* mem, const std::nothrow_t&) throw();

void* operator new[] ( std::size_t bytes) throw(...);
void operator delete[](void* p) throw();

void* operator new[]( std::size_t size, const std::nothrow_t&) throw();
void operator delete[](void* mem, const std::nothrow_t&) throw();

#ifdef WIN32
void *__CRTDECL operator new(std::size_t size) _THROW1(_STD bad_alloc);
#endif

These are the definitions

#ifdef WIN32
void *__CRTDECL operator new(std::size_t bytes) _THROW1(_STD bad_alloc)
{
    void* p = edb::g_getCurrentMemoryContext()->alloc(bytes);
    if (p==0) // did malloc succeed?
        throw std::bad_alloc(); // ANSI/ISO compliant behavior
    return p;
}

#endif

void operator delete(void* p) throw()
{
    edb::MemContext::free(p);
}

void* operator new( std::size_t bytes, const std::nothrow_t&) throw()
{
    return edb::g_getCurrentMemoryContext()->alloc(bytes);
}

void operator delete(void* p, const std::nothrow_t&) throw()
{
    edb::MemContext::free(p);
}

void* operator new[] ( std::size_t bytes) throw(...)
{
    void* p = edb::g_getCurrentMemoryContext()->alloc(bytes);
    if (p==0) // did malloc succeed?
        throw std::bad_alloc(); // ANSI/ISO compliant behavior
    return p;
}

void operator delete[](void* p) throw()
{
    edb::MemContext::free(p);
}

void* operator new[]( std::size_t bytes, const std::nothrow_t&) throw()
{
    return edb::g_getCurrentMemoryContext()->alloc(bytes);
}

void operator delete[](void* p, const std::nothrow_t&) throw()
{
    edb::MemContext::free(p);
}

And sometimes it picks up my definitions and sometimes it doesn't.

Thanks, Gokul.

Upvotes: 3

Views: 3092

Answers (1)

Andrew
Andrew

Reputation: 2568

Overridding the global new/delete in C++ is a tar baby. Yeah, it looks simple enough, but then you make one exception after another and you keep digging a deeper and deeper hole for yourself.

The reason why you're getting 'their new' and 'your delete' is that you're probably using some DLL that's already loaded and 'linked' to the existing new before yours is loaded. They allocate the object and then you're expected to delete it. You could try statically linking your program to resolve that.

Another way of handling this would be to refactor your code and override the new/delete as the base class and then make all of your classes inherit from that. Tedious for a large project with a lot of classes but it will disambiguate which new/delete gets called for whom.

If you're doing this as a presumably 'cheap' way of isolating a memory leak, consider something else. See if any of the vendors of instrumentation tools(purify for example) still have a '2-week' trial or run your linux version through valgrind.

Upvotes: 7

Related Questions