tags:

views:

146

answers:

6

As in topic.. I've found something like this in one application. In main C application we have declaration:

void* buff = NULL;

and later there is a call:

ReadData(&buff);
SaveToFile(buff);

SaveToFile() is a C function from main function.

ReadData(void* * ) is a C++ function from external dll. In this function memory for buffer is allocated by malloc function and filed with data.

So here is my question: is it correct?

A: 

Yes, this is correct. Memory in a process is equally accessible by all modules (EXE and DLLs) in that process.

MSalters
A: 

Yes, there is no problem with this.

caf
+1  A: 

It depends on the intention of the design and users the library is directed to. A better way is to take a buffer of some fixed size and fill it and return. But, you should be careful while freeing the buffer. It is better to call the free function (if any) provided by the third party DLL itself rather than calling free from your main.

In case of windows, if your third party DLL is using a different heap and if your application is using a different heap, it might lead to undefined behaviour. For Ex: if your third party DLL is build using VC8 and your application is built using VC6, then if you free the memory allocated by your external DLL, it will lead to problems.

Jay
+2  A: 

If both the DLL and the main executable were linked with the same C runtime, this is OK and you can call free() on the pointer to release it. However, a better idea is in the DLL to provide a function FreeData( void * ) which releases the data. In this way all memory management is done in the context of the DLL.

anon
+2  A: 

It's safe. However, you should always check:

  • if the same allocator is used for both allocation and deallocation
  • who is responsible for freeing (so there are no surprises)
  • watch out for any kind of automatic memory magement (if it's plain C/C++ then it's no problem).
Kornel Kisielewicz
+6  A: 

All modules in a running process share the same address space (doesn't care whether you're Windows or Linux or whatever actually, it's a common principle). However, be careful: reading or writing from module A to a buffer owned by module B is fine - but freeing the buffer is probably bad.

On Windows, it depends on the runtime library the application is linked against. If it is not the DLL runtime ('multithreaded dll'), every module maintains its own copy of the heap manager. Thus, the module that allocated a memory area must also be responsible for destroying it because only its own heap manager knows about it. If you follow this guideline, you won't run into problems (linking against the DLL runtime avoids the problem because all modules deal with the same heap manager residing somewhere in msvXXXnnn.dll, but gives rise to other issues).

Edit:

ReadData(void* * ) is a C++ function from external dll. In this function memory for buffer is allocated by malloc function and filed with data.

That might run into the aforementioned allocator issue. Either add another function to that DLL (FreeData) which is explicitly responsible for freeing up the buffer (as proposed by Neil Butterworth) and just calls its own free(). Or you add a DLL function to query the size of the buffer, allocate it upfront and pass it to ReadData (that's the cleanest choice imo).

Alexander Gessler
+1: woah, informed answer :D
Kornel Kisielewicz
It is always a good idea to read the other answers before answering yourself, or editing an existing answer.
anon