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. Heap Hell

Heap Hell

Scheduled Pinned Locked Moved C / C++ / MFC
debuggingdata-structuresperformancehelplearning
3 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.
  • M Offline
    M Offline
    Matthew Busche
    wrote on last edited by
    #1

    I have spent the last 24 hours tracking down a heap corruption problem. I think I now know vaguely what the problem is, but it has made it clear I have no idea what I'm doing when it comes to heap usage with DLLs under windows. I am hoping some seasoned windows programmer out there can first look at my sad story below, and then either educate me as to the do's and don'ts of heap usage with DLLs under windows or point me to an article or book that will educate me. I'm not looking to be an expert, but I don't want to hit any more snafus like this one. MY SAD STORY: I'm working on my first windows DLL. I have an exported function that looks much like this one:

    void \_\_declspec(dllexport) getCommandString(std::string& commandString);
    

    In case it's not obvious, usage of this function is for the application to pass in a string by reference, then some code in the DLL sets it for you. Perhaps you already know my problem. If you do, YOU are the person I hope to hear from. But I'll finish my sad story for those of you who don't. So I had some application code that called this function, much like this:

    void doSomething()
    {
        std::string commandString;
        getCommandString(commandString);
        // do some stuff with the string
        return;
    }
    

    doSomething() fails at the return statement with an assertion failure when memory for commandString was being freed. Digging into the stack trace I found the assertion failure was occuring somewhere in the implementation of this system call:

    HeapValidate( \_crtheap, 0, pHdr(pUserData) );
    

    I read the docs for HeapValidate and discovered you could set the thrid arg to NULL to force the entire heap to be validated. So I immediately had the idea of sprinkling my own calls to HeapValidate throughout my code to track down the time when I was corrupting the heap. But then I couldn't figure out where to get the symbol _crtheap. I could see it in the debugger, but couldn't find it declared in any headers that came with VC6. So I says to myself, "I'll just hard code the address since surely _crtheap won't change values from run to run." But this caused me problems too. Eventually I figured out that that value of the global symbol _crtheap was changing within a single run! After some additional contemplation, I says to myself, "Perhaps there is more than one heap for my process!" Through additional experimentation, I now believe that my DLL is allocating and freeing memory

    M 1 Reply Last reply
    0
    • M Matthew Busche

      I have spent the last 24 hours tracking down a heap corruption problem. I think I now know vaguely what the problem is, but it has made it clear I have no idea what I'm doing when it comes to heap usage with DLLs under windows. I am hoping some seasoned windows programmer out there can first look at my sad story below, and then either educate me as to the do's and don'ts of heap usage with DLLs under windows or point me to an article or book that will educate me. I'm not looking to be an expert, but I don't want to hit any more snafus like this one. MY SAD STORY: I'm working on my first windows DLL. I have an exported function that looks much like this one:

      void \_\_declspec(dllexport) getCommandString(std::string& commandString);
      

      In case it's not obvious, usage of this function is for the application to pass in a string by reference, then some code in the DLL sets it for you. Perhaps you already know my problem. If you do, YOU are the person I hope to hear from. But I'll finish my sad story for those of you who don't. So I had some application code that called this function, much like this:

      void doSomething()
      {
          std::string commandString;
          getCommandString(commandString);
          // do some stuff with the string
          return;
      }
      

      doSomething() fails at the return statement with an assertion failure when memory for commandString was being freed. Digging into the stack trace I found the assertion failure was occuring somewhere in the implementation of this system call:

      HeapValidate( \_crtheap, 0, pHdr(pUserData) );
      

      I read the docs for HeapValidate and discovered you could set the thrid arg to NULL to force the entire heap to be validated. So I immediately had the idea of sprinkling my own calls to HeapValidate throughout my code to track down the time when I was corrupting the heap. But then I couldn't figure out where to get the symbol _crtheap. I could see it in the debugger, but couldn't find it declared in any headers that came with VC6. So I says to myself, "I'll just hard code the address since surely _crtheap won't change values from run to run." But this caused me problems too. Eventually I figured out that that value of the global symbol _crtheap was changing within a single run! After some additional contemplation, I says to myself, "Perhaps there is more than one heap for my process!" Through additional experimentation, I now believe that my DLL is allocating and freeing memory

      M Offline
      M Offline
      Michael Dunn
      wrote on last edited by
      #2

      You've got it essentially right. The CRT new/delete operators alloc/free from a heap set up by the CRT. If the DLLs are linked statically to the CRT code, each DLL does its own CRT initialization, thus each gets a different heap. To alloc memory that's availble to the whole process, use CoTaskMemAlloc() and free it with CoTaskMemFree(). This prevents you from passing a string as a param, however. --Mike-- Ericahist | CP SearchBar v2.0.2 | Homepage | RightClick-Encrypt | 1ClickPicGrabber "That probably would've sounded more commanding if I wasn't wearing my yummy sushi pajamas."   -- Buffy

      F 1 Reply Last reply
      0
      • M Michael Dunn

        You've got it essentially right. The CRT new/delete operators alloc/free from a heap set up by the CRT. If the DLLs are linked statically to the CRT code, each DLL does its own CRT initialization, thus each gets a different heap. To alloc memory that's availble to the whole process, use CoTaskMemAlloc() and free it with CoTaskMemFree(). This prevents you from passing a string as a param, however. --Mike-- Ericahist | CP SearchBar v2.0.2 | Homepage | RightClick-Encrypt | 1ClickPicGrabber "That probably would've sounded more commanding if I wasn't wearing my yummy sushi pajamas."   -- Buffy

        F Offline
        F Offline
        forjer
        wrote on last edited by
        #3

        If I understand correctly, you can only pass string objects to exported functions if the dll was explicitly loaded via LoadLibrary?

        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