dan.p
dan.p

Reputation: 416

Bypass override of operator new in C++

Is there a way to achieve a bypass of an override of operator new?

Something like this:

void* ::operator new( std::size_t size ) {
    void *p = ( ::operator new( size ) );  // But original, _not_ infinite recursion
    // do stuff with p
    return p; 
}

Background: I have some legacy code, which we recently switched to compile with Visual Studio 2012. Now we get random crashes when malloc fails to _heap_alloc sufficient memory blocks. (Yes, the code is sprinkled with small memory leaks and other bad behaviour all over. But unfortunately a thorough cleanup is not realistic, it is somewhere around 500 000 SLOC.)

My current theory is that the cause is that almost all source files include a header with the following overrides of operator new:

void* ::operator new( std::size_t size ) {
    void* p = malloc( size );
    if( p == NULL )
        throw;
    // set memory to zero
    memset( p, 0, size );
    return p;
};

void* ::operator new[]( size_t count ) throw(std::bad_alloc) {
    // try to allocate count bytes for an array
    return (operator new(count));
}

There are no overrides of delete.

In essence, this means that the application mixes allocation using malloc with deallocation using delete instead of free.

First try to Q&D fix: Introduce overrides of delete that uses free. But this only partly helps, because sometimes include order and linked libraries still get it messed up.

Second try to Q&D fix: Remove the override. But the initialization of the memory to 0 is unfortunately necessary. A heritage from an old compiler used, which always did that, and coders that assumed C++ will always do that.

I am aware that new() will take care of that, but unfortunately i am not aware of any good method to make use of that without manually going through all the source code and updating it. It also won't help with poorly implemented classes which assumes all their members to be nullified without doing so in the constructor.

Therefore, my third idea of Q&D fix: Using the normal new in the override, as this question asks about.

Upvotes: 6

Views: 1912

Answers (1)

Solkar
Solkar

Reputation: 1226

Is there a way to achieve a bypass of an override of operator new?

None that I'm aware of, but why don't you simply re-implement it in your custom function in the same manner MS did it in their _heap_alloc-based implementation and just add your customization to it?

One do-or-die allocation attempt only is anyway not what MS does:

http://msdn.microsoft.com/en-us/library/vstudio/we2zys4d.aspx

The default behavior is to execute a loop. Within the loop, the function first attempts to allocate the requested storage

Anyway- I second what n.m. put in a comment

You need to fix real memory bugs

That is self-explaning; for those any debugging purposes - pls have a look at std::set_new_handler.

Btw - there some things that I find irritating about your code

  • the explicit qualifications of the operator
  • not throwing std::bad_alloc but re-throwing outside of a catch-block

Happy Hacking!

Regards, S.

P.S.:@all: I cannot "vote up" that question due my limited exp here, but I recommend doing that. It's a very interesting topic and a well formulated.

Upvotes: 2

Related Questions