4

I have to split my application into several logical modules.

mainapp:

  • module1.so
  • module2.so
  • module3.so
  • and so on

Where each module is an *.so library, which will be loaded during runtime.

Each module shares the same interface and will return some array of data. For example:

int *ptr = module1->getIntData();

Is it OK, to free/delete this memory on mainapp side?

int *ptr = module1->getIntData();
delete ptr; //(or free(ptr))

What about a malloc/free implementations. Is it possible, that library will use another one then mainapp?

Dejwi
  • 4,393
  • 12
  • 45
  • 74
  • 1
    You are probably OK, however it seems that if you provide a `createThing()` method you should also provide a `destroyThing()` method for consistency, if nothing else. – trojanfoe Apr 05 '16 at 07:51
  • Are you following any synchronisation mechanism? e.g. `mutex` or something alse. – someone Apr 05 '16 at 07:51
  • 1
    Actually it's more a matter of convention than a technical question. That is, technically it's ok, but it's important to explicitly agree which side owns data allocated by library methods. – user3159253 Apr 05 '16 at 07:52
  • 2
    Also I'd suggest to return something like [std::unique_ptr](http://en.cppreference.com/w/cpp/memory/unique_ptr), not raw pointers, because `unique_ptr`/`shared_ptr` allow to specify deleters upon object creation, thus simplifying memory management and making explicit remove functions excessive. – user3159253 Apr 05 '16 at 07:58
  • The choice between `unique_ptr`, `shared_ptr` and `weak_ptr` depends on ownership policy. – user3159253 Apr 05 '16 at 08:00

1 Answers1

5

I would strongly recommend that the module which does the allocation is also responsible for doing the de-allocation. Thus:

int *ptr = module1->getIntData();
...
module1->freeIntData(ptr);

This allows different modules to use different allocators (malloc/free, new/delete, slab allocator, etc) without difficulty.

On Posix systems there can only be one implementation of malloc (and free) in a process, so if the definition of getIntData is "returns a pointer which must be free'd by free" then you would be alright. On the other hand, I think it would be possible to write two C++ compilers which could be used to write module1 and module2, but which couldn't delete memory allocated by the other's new. (Although I don't think such compilers currently exist).

If there is the remotest glimmer of a chance you might ever have to port this lot to Windows, then you really want the modules to deallocate the memory they allocated. Different DLLs can have different heaps and all manner of fun problems can ensue. (As @trojanfoe says in comments: Just the difference between debug and release builds can be enough to cause grief.)

I would only recommend using std::unique_ptr if you can guarantee that all the modules are always going to be built with the same version of the same compiler using identical compiler flags. (I am a strong believer in keeping dynamic library interfaces as simple and C-like as possible.)