Global overload delete [] is not called in third-party libraries

I am trying to learn about memory pools in C ++ for better speed and debugging capabilities. I followed the approach found here: http://oroboro.com/overloading-operator-new/ . So I overloaded new , new[] , delete and delete[] as follows:

 inline void* operator new ( size_t size ) { return myAlloc( size ); } inline void* operator new[] ( size_t size ) { return myAlloc( size ); } inline void operator delete ( void* ptr ) { myFree( ptr ); } inline void operator delete[]( void* ptr ) { myFree( ptr ); } 

I like the fact that third-party libraries are aimed at this version of new , but I had a problem. I am making a DirectX application that uses DXUT. I compile DXUT separately from my project. In the end, it calls:

 std::unique_ptr<D3D11_SUBRESOURCE_DATA[]> initData( new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] ); 

As soon as this unique pointer goes out of scope, it crashes when calling delete[] _Ptr , which did not go through my overloaded operator. I tried to debug the implementation of the memory pool by adding int* dummy = new int[10]; delete[] dummy; int* dummy = new int[10]; delete[] dummy; in my main . Building the project gave a mistake, but clean construction worked great. To my surprise, everything worked, including the DXUT line, which was crashing!

Question 1: What exactly happened when I added a debug line that fixed the problem? I think for some reason my delete [] operator was not known until I named it in my own application code? Is it guaranteed to fix the problem or is it just stupid?

Question 2: I noticed that new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] did not call my operator new[] directly, but called my operator new (without brackets). It still calls the delete[] operator on the pointer. This is problem? Should I add the appropriate overload to call my operator new[] or is this behavior fine?

For reference, the operator new[] overload that was called was:

 void * __CRTDECL operator new[](::size_t count, const std::nothrow_t& x) _THROW0() { // Try to allocate count bytes for an array return (operator new(count, x)); } 
+6
source share
1 answer

Question 1: What exactly happened when I added a debug line that fixed the problem? I think for some reason my delete [] operator was not until I called my own application code? Is it guaranteed to fix the problem or is it just stupid?

ยง3.2 [basic.def.odr] / p4:

A built-in function must be defined in each translation unit in which it is used odr.

It seems that your compiler did not generate code for the global operator delete[] , since it was not used in your main translation unit and is marked inline (this means that the compiler can assume that any translation unit that uses them will have their definition ) However, your separately compiled library does not have a definition of these functions, and you end up using the standard ones from the standard library. Make them not inline should fix the problem.

Question 2: I noticed that new (std::nothrow) D3D11_SUBRESOURCE_DATA[ mipCount * arraySize ] did not call my operator new[] directly, but it was ultimately called my operator new (no brackets). It still calls the delete[] operator on the pointer. Is this a problem? Should I add an appropriate overload such that my operator new[] is called, or is this behavior fine?

The standard versions of both metallic and non-inversion versions of operator new [] , as well as the non-inverting version of operator new are set to call the metallic version of operator new to obtain memory. Thus, you are safe. However, your definitions of operator new are most likely incorrect. They must return a valid pointer or throw an exception. Returning a null pointer is not allowed.

+4
source

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


All Articles