Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. DLL/App Memory Allocation

DLL/App Memory Allocation

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++performancequestion
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Steve The Plant
    wrote on last edited by
    #1

    Hi! A dynamically loaded DLL I wrote receives a pointer to a class that I pass to it from the client app. A certain method in that class, (let's call it) cClass::AllocMem()is called inside the DLL to allocate some memory. The "problem" is that the allocated memory is stored on the heap of the DLL, as opposed to the heap of the client app, which is where I'd like it to reside. Is there any way for me to still be able to call this AllocMem() method inside the DLL and have the memory allocated inside the client app's heap? This is just a plain vanilla Win32 application and DLL. I know in MFC, there the AFX_MANAGE_STATE() macro to help out with these things, but it is unavailable to me. Does anybody have any ideas? Thanks a bunch! Steve The Plant

    J 1 Reply Last reply
    0
    • S Steve The Plant

      Hi! A dynamically loaded DLL I wrote receives a pointer to a class that I pass to it from the client app. A certain method in that class, (let's call it) cClass::AllocMem()is called inside the DLL to allocate some memory. The "problem" is that the allocated memory is stored on the heap of the DLL, as opposed to the heap of the client app, which is where I'd like it to reside. Is there any way for me to still be able to call this AllocMem() method inside the DLL and have the memory allocated inside the client app's heap? This is just a plain vanilla Win32 application and DLL. I know in MFC, there the AFX_MANAGE_STATE() macro to help out with these things, but it is unavailable to me. Does anybody have any ideas? Thanks a bunch! Steve The Plant

      J Offline
      J Offline
      Joaquin M Lopez Munoz
      wrote on last edited by
      #2

      Have you tried declaring cClass::AllocMem() as virtual? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

      S 1 Reply Last reply
      0
      • J Joaquin M Lopez Munoz

        Have you tried declaring cClass::AllocMem() as virtual? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

        S Offline
        S Offline
        Steve The Plant
        wrote on last edited by
        #3

        Well, I tried and it worked! But I don't understand why. Does it have anything to do the class' virtual table when you pass it to the DLL? Steve The Plant

        J 1 Reply Last reply
        0
        • S Steve The Plant

          Well, I tried and it worked! But I don't understand why. Does it have anything to do the class' virtual table when you pass it to the DLL? Steve The Plant

          J Offline
          J Offline
          Joaquin M Lopez Munoz
          wrote on last edited by
          #4

          Well, actually it's magic ;P Now seriously, what's happening here is this: Both your client app and your DLL are having access to cClass.h and cClass.cpp, and both modules are subsequently compiling and linking their own copies of cClass::AllocMem(). Now, when you pass a pointer to a cClass object created by the app to the DLL, and the DLL code executes pcClass->AllocMem(), what it is actually doing is invoking its own version of cClass::AllocMem() against pcClass: crash promptly ensues when the clients tries to free the memory allocated, for the reasons you already diagnosed. Now, if you make cClass::AllocMem() virtual, then the DLL does not execute any local version of the method, but instead uses pcClass to locate its associated virtual table and AllocMem() implementation, both of which reside at the app's home (which originally created the object). Having things arranged like this, you can even remove cClass.cpp from the DLL build and things will still work as long as the DLL limits itself to handle cClass pointers passed from the app, and all relevant methods are virtualized. This is also a good thing to have in the light of OO, as it defines an interface contract between the app and the DLL and allows you to change the implementation code without the DLL knowing nor having to be recompiled. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

          S 1 Reply Last reply
          0
          • J Joaquin M Lopez Munoz

            Well, actually it's magic ;P Now seriously, what's happening here is this: Both your client app and your DLL are having access to cClass.h and cClass.cpp, and both modules are subsequently compiling and linking their own copies of cClass::AllocMem(). Now, when you pass a pointer to a cClass object created by the app to the DLL, and the DLL code executes pcClass->AllocMem(), what it is actually doing is invoking its own version of cClass::AllocMem() against pcClass: crash promptly ensues when the clients tries to free the memory allocated, for the reasons you already diagnosed. Now, if you make cClass::AllocMem() virtual, then the DLL does not execute any local version of the method, but instead uses pcClass to locate its associated virtual table and AllocMem() implementation, both of which reside at the app's home (which originally created the object). Having things arranged like this, you can even remove cClass.cpp from the DLL build and things will still work as long as the DLL limits itself to handle cClass pointers passed from the app, and all relevant methods are virtualized. This is also a good thing to have in the light of OO, as it defines an interface contract between the app and the DLL and allows you to change the implementation code without the DLL knowing nor having to be recompiled. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

            S Offline
            S Offline
            Steen Krogsgaard
            wrote on last edited by
            #5

            Waitasecond! According to Richter there is no such thing as a local DLL heap in Win32. The DLL uses the heap of the client process. So unless the DLL in question here creates it's own heap using HeapCreate then the OP's problem cannot be caused by allocation of different heaps. Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

            J 1 Reply Last reply
            0
            • S Steen Krogsgaard

              Waitasecond! According to Richter there is no such thing as a local DLL heap in Win32. The DLL uses the heap of the client process. So unless the DLL in question here creates it's own heap using HeapCreate then the OP's problem cannot be caused by allocation of different heaps. Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

              J Offline
              J Offline
              Joaquin M Lopez Munoz
              wrote on last edited by
              #6

              All right all right. The picture is larger than I showed, but, taken literally, Richter is wrong. What is causing these problems with allocating memory on one side and deallocating at the other is the C runtime library (CRT) used by each of the parts. As you know, the CRT comes in six flavors:

              • (Release) Single-Threaded
              • (Release) Multithreaded
              • (Release) Multithreaded DLL
              • Debug Single-Threaded
              • Debug Multithreaded
              • Debug Multithreaded DLL

              Let's begin with the debug/release aspect. In debug mode, standard C/C++ functions like malloc() and new allocate, when requested a memory block, additional info about the block than can be later used to identify out of bounds errors and stuff like that. This info is stored contiguously to the block delivered to the app, so that when free() or delete are invoked, these functions know where the info should be with respect to the pointer to deallocate. Now, if your app uses a debug CRT and the DLL a release one, and the DLL malloc()s some memory and the app tries to free() it, a crash will follow as the debug CT cannot find that additional info I talked about. Other similar scenarios involving debug/release mixing follow analogous patterns. Now for the DLL/not DLL option. If you choose not DLL, then the CRT is linked as a static library to your app (or DLL). The CRT maintains a private heap (yes, it does) called _crtheap which is created upon initiation of the app (or the DLL). So, even if you use the exact same version of CRT in static mode for your app and your DLL, your final executable will end up with two _crtheaps accessed respectively from the app CRT and the DLL CRT code. As before, allocating on one side and deallocating on the other leads to catastrophe. Enough is enough. It is simple to check that all combinations of CRTs exhibit this problem except if both the app and the DLL use the same CRT version and this CRT is linked as a DLL. Then, only one _crtheap exists, shared by all folks in the program, and all other aspects being equal (debug/release, multithreaded/single threaded) things run smooth. The moral of the story: Expect problems when passing around the responsibility of freeing a CRT-allocated chunk of memory except if you are 100% sure all parts involved (app, DLLs) use the same CRT version and this is linked dynamically. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

              S 1 Reply Last reply
              0
              • J Joaquin M Lopez Munoz

                All right all right. The picture is larger than I showed, but, taken literally, Richter is wrong. What is causing these problems with allocating memory on one side and deallocating at the other is the C runtime library (CRT) used by each of the parts. As you know, the CRT comes in six flavors:

                • (Release) Single-Threaded
                • (Release) Multithreaded
                • (Release) Multithreaded DLL
                • Debug Single-Threaded
                • Debug Multithreaded
                • Debug Multithreaded DLL

                Let's begin with the debug/release aspect. In debug mode, standard C/C++ functions like malloc() and new allocate, when requested a memory block, additional info about the block than can be later used to identify out of bounds errors and stuff like that. This info is stored contiguously to the block delivered to the app, so that when free() or delete are invoked, these functions know where the info should be with respect to the pointer to deallocate. Now, if your app uses a debug CRT and the DLL a release one, and the DLL malloc()s some memory and the app tries to free() it, a crash will follow as the debug CT cannot find that additional info I talked about. Other similar scenarios involving debug/release mixing follow analogous patterns. Now for the DLL/not DLL option. If you choose not DLL, then the CRT is linked as a static library to your app (or DLL). The CRT maintains a private heap (yes, it does) called _crtheap which is created upon initiation of the app (or the DLL). So, even if you use the exact same version of CRT in static mode for your app and your DLL, your final executable will end up with two _crtheaps accessed respectively from the app CRT and the DLL CRT code. As before, allocating on one side and deallocating on the other leads to catastrophe. Enough is enough. It is simple to check that all combinations of CRTs exhibit this problem except if both the app and the DLL use the same CRT version and this CRT is linked as a DLL. Then, only one _crtheap exists, shared by all folks in the program, and all other aspects being equal (debug/release, multithreaded/single threaded) things run smooth. The moral of the story: Expect problems when passing around the responsibility of freeing a CRT-allocated chunk of memory except if you are 100% sure all parts involved (app, DLLs) use the same CRT version and this is linked dynamically. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

                S Offline
                S Offline
                Steen Krogsgaard
                wrote on last edited by
                #7

                Wow! You really do know what you're talking about, don't you? I stand corrected, I bow my head before you ;-) I did a search on MSDN on the subject (yeah, I know, should have done it before), and article Q190799 does a pretty good job explaining things (at least after I had read your post first :-) I will immidiately check if my current multi-DLL application project is linked to the MT DLL version! Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups