3

I have a wrapper DLL that interfaces to another DLL that contains the following function:

char * Foobar(void)
{

    // BLAH is the function from the DLL this wrapper interfaces too
    char *array = 0; // Set up an array pointer for dynamic memory allocation.
    int NumOfChar = 0;

    // Build array
    for (int n=0; (*(BLAH+n) != '\0'); n++)
    {
            NumOfChar++; // keep track of how big BLAH is.
    }

    NumOfChar++;    // +1 so I can re-add the NULL

    // Try to allocate an array based on the size of BLAH This is dynamic...
    if (!(array = new char[NumOfChar]))
    {   
        // If there's a problem allocating the memory, pop up a message.
        MessageBox (0, "Error: out of memory.", "Crap", MB_OK); 
    }
    else
    {
        memcpy(array, BLAH,(NumOfChar)); // copy the contents of BLAH to array.
    }

    array[NumOfChar+1]='\0'; // ensure the last character is a NULL

    FreeLibrary(hGetProcIDDLL); // release the DLL

    return array;   
}

I am calling this DLL from LabVIEW which is don't think is specific to this question, as the DLL can be called by any program. My question is once Foobar returns the pointer to the array, how can I make sure that the array is deallocated afterwards? This seems to be a memory leak, because next time this routine is called, the next array won't necessarily overwrite the old array. It will just use up more and more memory, am I correct in this logic?

Thank you

  • By the way, array[NumOfChar+1]='\0' exceeds the array bounds. The maximum index is NumOfChar-1. If you null-terminate, you need to allocate NumOfChar+1 items to accommodate for the last null. – Joonas Pulakka Apr 17 '14 at 13:53
  • You mention DLLs and memory deallocation, so I assume this is C or C++ on Windows? In that environment, memory belongs to the executable unit (EXE, DLL) that allocates it and no other unit can deallocate it. So if a DLL calls malloc() or new, it must also call free() or delete on that same pointer. – user22815 Apr 17 '14 at 18:12
4

Yes, you're allocating memory but not freeing it, so there is a memory leak.

A good approach is to allocate and deallocate the memory in the same place, i.e. wherever the DLL is called from - in your case, LabVIEW. That is, make your function void Foobar(char *array) (or int Foobar(char *array) and return the array length). Then you just need to make sure you call the function with big enough array. Perhaps add another parameter do indicate the maximum allowed length, int Foobar(char *array, int maxLen) to react instead of crashing in case of insufficient length.

  • One can also go about it another way. Have the wrapper method clean up after itself, store the results into a pointer that LabView has full control over, and when its done free the memory of that pointer. – Ramhound Apr 17 '14 at 15:57
  • Joonas Pulakka I rewrote the function to return void and accepts a pre-allocated buffer as a pointer. The only problem I'm having is if the parent process reloads the DLL, there is an access violation somewhere in the DLL – zacharoni16 Apr 17 '14 at 21:31
  • Could it be the array[NumOfChar+1]='\0' that I mentioned in the comments? Why do you need to reload the DLL, couldn't it be just loaded once when the process starts? – Joonas Pulakka Apr 18 '14 at 7:27
0

Another approach is to return the char* wrapped in a smart pointer, like

// If you want several scopes keeping references to the same memory
std::shared_ptr<char> Foobar(void)

//or (if you only want a single reference to be available)

std::unique_ptr<char> Foobar(void)

Notices, that the previous two types (std::shared_ptr & std::unique_ptr) were introduced recently to the STL. If that is the case, you can use boost, then you can have

boost::shared_ptr<char> Foobar(void) // for example.

Note for VC++: Both the client code and the DLL (with Foobar) must be compiled with the same version of the MSVC runtime, like both MSVC2013 or both MSVC2015 (which is not a problem in modern VC++, since that is enforced by linker I think). The client also must be compiled with MD runtime. For more details on this, see https://blogs.msdn.microsoft.com/oldnewthing/20060915-04/?p=29723

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.