Override new operator in C ++, while crtdbg.h causes conflicts

While trying to track and prepare for memory of my own memory manager, I tried to override the new statement. The flip code article was my main guide in this process ( http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml ).

After implementing the methods described in this article, I remain with the problem that somewhere in the STL "crtdbg.h" is included directly or indirectly through some of the header files that are included (using Visual Studio 2010).

This will result in an error:

[...]10.0\vc\include\crtdbg.h(1078): error C2365: 'operator new' : redefinition; previous definition was 'function' [...]10.0\vc\include\crtdbg.h(1078): error C2078: too many initializers [...] 

Performing a quick check by placing "_CrtDumpMemoryLeaks ()" without including header files confirms my suspicion that the header files are indeed included in the STL files.

 // The header files that should be included for using the CrtDumpMemoryLeaks: //#define _CRTDBG_MAP_ALLOC //#include <stdlib.h> //#include <crtdbg.h> //... _CrtDumpMemoryLeaks() 

Leaving aside, even if it is a good idea or not to implement my own new / delete, I wonder how I can have my own new / removed implementations, still using some standard library functions and not having these override errors.


The code is as follows:

memdebug.h

 #ifndef _MEM_DEBUG_H #define _MEM_DEBUG_H #ifdef _DEBUG void * operator new( unsigned int size, const char *filename, int line ); void operator delete( void *ptr ); #define DEBUG_NEW new(__FILE__, __LINE__) #define new DEBUG_NEW #endif #endif 

memdebug.c

 #ifdef _DEBUG void * operator new( unsigned int size, const char *filename, int line ) { void *ptr = (void *)malloc(size); //AddTrack((DWORD)ptr, size, filename, line); return(ptr); }; void operator delete( void *ptr ) { //RemoveTrack( (DWORD)ptr ); free( ptr ); } #endif 

main.cpp

 #include "memdebug.h" #include <iostream> void main() { Test *pTest = new Test(); std::cout << "end" << std::endl; } 

How I solved this by moving #define new DEBUG_NEW below <iostream> ; The problem is resolved because it will not rewrite the new in crtdbg.h ; however, it does make it difficult to make sure that it always runs after possible headers containing the crtdbg.h file.

I believe that this can only be solved with a custom name for the new operator and use it instead. Am I right?

+4
source share
4 answers

Well, as I solved it now, without using a custom "new" definition - this is that I created a common header file, let's say that "Engine.h" is included in each file. This can be done using the Forced Include file in Project Settings / Configuration Properties / C / C ++ / Advanced .

This file contains #define (removed from memdebug.h)

engine.h

 #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #include <windows.h> #include "MemoryNappy.h" #define DEBUG_NEW new(__FILE__, __LINE__) #define new DEBUG_NEW 

This forces the system to examine crtdbg.h before the user-defined new-define and will not modify the new one there. The second time, when he connected somewhere in the line, he simply used the data that had already been downloaded before. (If <iostream> turned on after turning on "engine.h" ).

Note that redefining a new operator is still a risky business when using third-party libraries that can do the same trick. This causes the new statement for these files to be overwritten using the template used here. In this case, you may need to reconsider using a custom new definition, as in this snippet:

 #define myNew new(__FILE__, __LINE__) 

(Also described at http://www.flipcode.com/archives/Detecting_Memory_Leaks.shtml )

+3
source

In one of our applications, we resorted to renaming everywhere at the application level new with xnew , and then we define the debug macro to be valid only on xnew .

Using new and redefining it as a macro can also have problems with custom allocators. Unfortunately, the C ++ syntax for placement made debugging wrappers more difficult.

+2
source

In Visual Studio 2010, I was able to do this without overriding new or custom new ones. I created a header file with the following:

 #pragma once //_CRTDBG_MAP_ALLOC //_CRTDBG_MAP_ALLOC_NEW #define _CRTDBG_MAP_ALLOC #define _CRTDBG_MAP_ALLOC_NEW #include <stdlib.h> #include <crtdbg.h> 

and forcibly included it in each source file with the option to force the file to be included in the Project Settings / Configuration Properties / C / C ++ / Advanced option already discussed. In fact, crtdbg.h already fulfills this custom definition of new , as well as the uncertainty of a regular new . And to make sure everything worked smoothly, I added _CRTDBG_MAP_ALLOC and_CRTDBG_MAP_ALLOC_NEW to the Preprocessor list Definition , available in: Project Settings / Configuration Properties / C / C ++ / Preprocessor .

Hope this helps in this matter.

0
source

Try _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - as described in my blog post , no override of new is required.

-1
source

Source: https://habr.com/ru/post/1340483/


All Articles