How to write a small memory leak detection in C ++?

I am trying to write a small memory leak detection tool.

My idea is to keep track of the dynamic memory allocation in my application to determine any invalid access to memory or remote memory, which could cause my application to become the kernel for the duration of use.

I want to write a simple interface to override new and delete .

And in my overridden new I wanted to print the address of the function string, etc. Then call the standard new .

Has anyone already tried this? I'm not sure if I can name a standard new from my new class statement.

+4
source share
4 answers

In this question, I suggested an ad-hoc solution to your problem: Immediately detect heap corruption errors in Windows. How?

In general, you can replace your new and delete with this code:

 DWORD PageSize = 0; inline void SetPageSize() { if ( !PageSize ) { SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); PageSize = sysInfo.dwPageSize; } } void* operator new (size_t nSize) { SetPageSize(); size_t Extra = nSize % PageSize; nSize = nSize + ( PageSize - Extra ); return Ptr = VirtualAlloc( 0, nSize, MEM_COMMIT, PAGE_READWRITE); } void operator delete (void* pPtr) { MEMORY_BASIC_INFORMATION mbi; VirtualQuery(pPtr, &mbi, sizeof(mbi)); // leave pages in reserved state, but free the physical memory VirtualFree(pPtr, 0, MEM_DECOMMIT); DWORD OldProtect; // protect the address space, so noone can access those pages VirtualProtect(pPtr, mbi.RegionSize, PAGE_NOACCESS, &OldProtect); } 

to determine invalid memory access. In the following discussion, you will find ideas for detecting leaks and detecting other memory errors.

If you want to call global new and delete , you can use the :: global namespace prefix prefix:

 return ::new(nSize); 
0
source

Calling ::operator new from the operator new class for the class is nice and fairly common. You cannot call the global operator new from the replacement version ::operator new , because if you replace the global operator new, the old one does not exist.

0
source

The described approach sounds reasonable. You can improve it and save some bits of data identification for each distribution in some data structure. Thus, you can track all non-running memory after the program terminates without having to check all the allocation / deallocation logs.

To detect damage, you can wrap each selection with pads before and after the end and fill it with some predefined pattern. After freeing up memory, you can verify that the templates are still in place. This will give you a good chance to detect corruption.

You can call global new with a scope prefix: ::new .

0
source

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


All Articles