The “function redefinition error” is probably because you’re using MFC.
The runtime library should not be in the business of defining such allocation and deallocation functions.
The current code’s
struct MemLeakInfo
{
unsigned int addr;
unsigned int line;
unsigned int size;
unsigned char file;
};
is ungood. An unsigned int
is not guaranteed to be large enough to hold an address, even though it is in 32-bit Windows. Instead, use intptr_t
.
Also, the current code’s
void* operator new(unsigned int Size, int Line, const char* File);
is ungood. That should be …
void* operator new( size_t Size, int Line, const char* File );
And you need a corresponding operator delete
, like …
void* operator delete( void* p, int Line, const char* File );
in order to deallocate memory from a failed constructor call. It's only called in that very specific situation. But if you don’t have it, then you have a leak, as MFC once had for debug builds.
EDIT: fixed versions of the code you now provided:
file [minimal.h]:
_MINIMAL_H
is invalid, because it starts with underscore followed by uppercase letter, which is reserved. Changed to MINIMAL_H
.
- to use
size_t
you need to include <stddef.h>
.
_DEBUG
is not a standard macro. it's a microsoftism. the standard macro (look up documentation of assert
) for this purpose is NDEBUG
.
#ifndef MINIMAL_H
#define MINIMAL_H
#include <stddef.h> // std::size_t
#ifndef NDEBUG
void* operator new( size_t Size, int Line, const char* File );
void* operator new[]( size_t Size, int Line, const char* File );
void operator delete( void* ptr, int Line, const char* File );
void operator delete[]( void* ptr, int Line, const char* File );
#endif
#ifndef NDEBUG
#define DEBUG_NEW new( __LINE__, __FILE__ )
#else
#define DEBUG_NEW new
#endif
#endif //MINIMAL_H
file [minimal.cpp]:
- to use
malloc
you need to include stdlib.h
.
- when you
#define new
you’re wreaking havoc with the new
keywords in the following code.
- in C you should never cast the result of
malloc
, and in C++ you should only cast something when there is a need for it. there is no such need here. casts only mask bugs, and that's not a good idea.
- missing return in error case. for error you need to
throw std::bad_alloc
. that's by the holy standard’s specification of these functions.
#include "Minimal.h"
//#define new DEBUG_NEW
#ifndef NDEBUG
#include <stdlib.h> // malloc
#include <exception> // std::bad_alloc
void* operator new( size_t const size, int, const char*)
{
void* const ptr = malloc( size );
if( !ptr ) { throw std::bad_alloc(); }
return ptr;
};
void* operator new[]( size_t const size, int, const char*)
{
void* const ptr = malloc( size );
if( !ptr ) { throw std::bad_alloc(); }
return ptr;
}
void operator delete(void* const ptr, int, const char*)
{
free( ptr );
};
void operator delete[]( void* const ptr, int, const char* )
{
free( ptr );
};
#endif