Do (statically linked) DLLs use a different heap than the main program?

I am new to Windows programming, and I just β€œlost” two hours hunting for an error that everyone seems to know about: you cannot create an object on the heap in a DLL and destroy it in another DLL (or in the main program).

I am pretty sure that on Linux / Unix this is not the case (if so, tell me about it, but I'm sure I did it thousands of times without any problems ...).

At this point, I have a few questions:

1) Do statically linked DLL files use a different heap than the main program?

2) Is a statically linked DLL mapped to the same process space of the main program? (I am quite sure that the answer here is a big YES, otherwise it would not make sense to pass pointers from a function in the main program to a function in the DLL).

I'm talking about a simple / regular DLL, not COM / ATL services

EDIT: "statically linked" I mean that I do not use LoadLibrary to load the DLL, but I am linking to the stub library

+19
heap linux windows dll heap-corruption
May 30 '12 at 16:11
source share
3 answers

DLL / exes will need to be associated with the implementation of the C runtime libraries.

In the case of C Windows Runtime libraries, you can specify if you want to reference the following:

  • Single-threaded C runtime library (support for single-threaded libraries is now discontinued)
  • Multi-threaded DLL / multi-threaded DLL for debugging
  • Libraries of time of static time.
  • A bit more (you can check the link)

Each of them will refer to another heap, so you are not allowed to pass the address obtained from the heap of one runtime library to another.

Now it depends on which C runtime library the DLL you are talking about is associated with. Suppose that your DLL is linked to the C static runtime library, and your application code (containing the main function) is linked to the multi-threaded C Runtime DLL, then if you pass a pointer to the memory allocated in the DLL in your main program and try release it, or vice versa, this can lead to undefined behavior. Therefore, the main underlying reason is the C runtime libraries. Please select them carefully.

For more information on C runtime libraries, here and here.

Quote from MSDN:

Caution Do not mix static and dynamic versions of runtime libraries. Having multiple copies of the run-time libraries in the process can cause problems because static data in one copy is not shared with another copy. The compiler does not allow you to link to both static and dynamic versions in a single .exe file, but you can still get two (or more) copies of the runtime libraries. For example, a dynamic link library associated with static (non-DLL) versions of runtime libraries can cause problems when using an .exe file that was associated with a dynamic (DLL) version of runtime libraries (you should also avoid mixing debug and debug versions of libraries in one process.)

+18
May 30 '12 at 16:15
source share

If I have an application that compiles as .exe and I want to use the library, I can either statically link this library from the .lib file, or dynamically link this library from the .dll file.

Each associated module (i.e., each .exe or .dll) will be associated with a C or C ++ runtime implementation. Runtimes themselves are a library that can be statically or dynamically linked to various thread configurations.

Speaking of statically linked dlls, do you describe a setup in which a .exe application dynamically links to a .dll library, and does this library statically link to a runtime? I will assume that this is what you mean.

It is also worth noting that each module (.exe or .dll) has its own scope for statics, i.e. global statics in .exe will not be the same instance as global statics with the same name in .dll.

Therefore, in the general case, it cannot be assumed that lines of code running inside different modules use the same implementation of the runtime; moreover, they will not use the same instance of any static state.

Therefore, when working with objects or pointers that cross the boundaries of modules, certain rules must be followed. Allocations and releases must occur in the same module for any given address. Otherwise, the heaps will not match and the behavior will not be determined.

COM solves this problem with reference counting; objects are deleted when the reference count reaches zero. This is a generic pattern used to solve a consistent location problem.

There may be other problems, for example, windows defines certain actions, for example, how allocation failures are handled for each thread, and not for each module. This means that the code executed in module A in the thread configured by module B can also work in an unexpected way.

+4
May 30 '12 at 16:37
source share

Lets you first understand the heap distribution and stack in Windows for our applications / DLLs. Traditionally, the operating system and runtime libraries include heap implementations.

  • At the beginning of the process, the OS creates a default heap called the Process heap. A process heap is used to allocate blocks unless another heap is used.
  • Language runtimes can also create individual heaps in a process. (For example, C runtime creates its own heap.)
  • In addition to these dedicated heaps, an application program or one of the many loaded dynamic link libraries (DLLs) can create and use separate heaps, called private heaps.
  • This heap is on top of the Virtual Memory Manager operating system in all virtual memory systems.
  • Let's discuss more about CRTs and related heaps:
    • C / C ++ Runtime Distributor (CRT): provides malloc () and free () functions, as well as new and remote operators.
    • CRT creates such an extra heap for all its distributions (the handle of this CRT heap is stored inside the CRT library in a global variable called _crtheap) as part of its initialization.
    • CRT creates its own heap that sits on top of the Windows heap.
    • The Windows heap is the thin layer surrounding the Windows Runtime Manager (NTDLL).
    • The Windows Runtime Distributor interacts with the Virtual Memory Allocator, which reserves and captures the pages used by the OS.

Your DLL and exe link to multi-threaded static CRT libraries. Each DLL and exe that you create has its own heap, i.e. _crtheap. Allocations and deductions must come from the corresponding heap. What is dynamically allocated from a DLL cannot be extracted from an executable file and vice versa.

What can you do? Compile our code into DLLs and exes using / MD or / MDd to use the multi-threaded and DLL-specific version of the runtime library. Therefore, both the DLL and exe are associated with the same C runtime library, and therefore with the same _crtheap. Allocations are always associated with de-distributions in one module.

+4
Apr 04 '14 at 9:41
source share



All Articles