0

I had some problem with inter-module memory allocation / deallocation. It seems like this post describes the same error.

Here is a piece of code:

My main application:

#pragma comment(lib, "mydll.lib")
__declspec(dllimport) std::shared_ptr<VOID> GetMemory(size_t size);

int wmain(int argc, wchar_t* argv[])
{
    std::shared_ptr<VOID> lpMem = GetMemory(100);    
    return 0;
}

Dll code:

__declspec(dllexport) std::shared_ptr<VOID> GetMemory(size_t size);

BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID)
{
    return TRUE;
}

std::shared_ptr<VOID> GetMemory(size_t size)
{
    return std::shared_ptr<VOID>(new (std::nothrow) char[size]);
}

Either /MT or /MD compiler flags are processed correctly. And execution does not fail.

My question is: why does the solution with std::shared_ptr work properly? What does it change? And what are those "memory managers" (mentioned in the thread linked above), which are different within a single process? Is that just an CRT abstraction? Or, may be CRT provides some specific implementation of memory allocations?

I think, any call of new / malloc / LocalAlloc leads to the HeapAlloc. Am I right? If so, why new/delete-calls (not wrapped with the std::shared_ptr) in different modules within a single process lead to crash?

Community
  • 1
  • 1
John Smith
  • 89
  • 11

1 Answers1

3

Re

why does the solution with std::shared_ptr work properly?

Because you have undefined behavior, and UB includes that what you hoped would happen, happens. It's UB because an object created with a new[] expression needs to be destroyed with a delete[] expression. The shared_ptr instead destroys, by default, via a delete expression.

This is irrespective of involving a DLL or not.


Re

What does [use of shared_ptr] change?

In the DLL scenario it makes it possible to bundle a deleter function that invokes the DLL-specific deallocation function.

However, you would still have a potential problem due to allocation of the shared_ptr's control block. Whether this manifests as an actual problem depends on your build setup (e.g. shared runtime library?) and on which toolchain you're using.


Re

And what are those "memory managers" (mentioned in the thread linked above), which are different within a single process

Presumably the runtime in each DLL.

If all DLLs as well as the main program are linked against a single common DLL runtime, not a static library runtime, then all are using the same shared memory management, and that part is OK.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Thank a lot for an answer. Yeah, I see that problem with undefined behaviour. I shouldn't have rushed with a code sample. And what about "DLL-specific deallocation function"? Why is it dll-specific. What is the reason of being _DLL-specific_? – John Smith Feb 15 '16 at 10:45
  • @MAKAKOKO: Mainly that a DLL can link to a different runtime library (either statically or as DLL) than the main program or other DLLs in this process. When the runtime library is linked statically by the DLL it is different automatically, because the DLLs instance has its own variables that keep track of memory regions etc. Note that this is different for Unixland shared libraries. – Cheers and hth. - Alf Feb 15 '16 at 10:58