Is it safe to call delete on a base-class pointer to a heap object allocated by a dynamically loaded library? Both that lib and the client were built by the same compiler (GCC).
-
(The loaded lib allocates it by calling "new" in the usual way - not using in-place "new" upon a memory address I provide to it, or anything like that.) – Keith Russell Feb 22 '17 at 17:00
-
1Looks like this question comes from usage of MS stuff. No, Linux/Unix system implemented shared libs properly the first place, not that crap from MS – Slava Feb 22 '17 at 17:20
-
If I could find an official-ish reference saying as much, that'd solve my problem. :) – Keith Russell Feb 22 '17 at 17:25
-
1@KeithRussell there is no universal official reference about shared libraries in C++, because the standard does not specify shared libraries. To find official documentation you must limit your search to particular implementation of shared libraries. – eerorika Feb 22 '17 at 17:28
-
@KeithRussell this is normal way which should work by default, MS as usually ignored standard and made their own way. So I doubt you would find official reference that Linux does it properly. – Slava Feb 22 '17 at 17:36
3 Answers
It is safe to delete
the pointer if and only if
- The destructor of the base class is virtual.
- The pointer was returned by
new
(notnew[]
, notmalloc
, notmmap
, ...) - You are the sole owner of the pointer. In other words: If no other piece of code (within or out of the dll) is going to use or destroy the pointed object.
As far as the standard is concerned, the library must have linked with the same version of runtime library that define the allocation functions. Same requirement applies to separate object files that are linked together statically.
Technically multiple different implementation of memory allocation functions violates the one definition rule, but a C++ implementation that extends the language with standard libraries may possibly extend the language to allow multiple different implementations for those functions. If that is the case for the implementation that you use, then it might not be safe to deallocate memory allocated by the shared library unless you can prove that same versions were used for both the library and the code that deletes the object.
Whether it is safe or not, it is a bad idea to provide an API that returns resources (such as dynamic memory), but not API that takes care of releasing those resources.

- 232,697
- 12
- 197
- 326
-
1Wrong, the destructor doesn't have to be virtual for the delete to be safe. It only has be virtual if you want any derived class destructors to be called. – Emil Laine Feb 22 '17 at 16:59
-
1@tuple_cat *"if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and **the static type shall have a virtual destructor or the behavior is undefined**."* So sayeth the standard. – eerorika Feb 22 '17 at 17:01
-
@tuple wrong - the standard says that deleting a derived object via a base pointer is undefined behaviour if the base destructor is not virtual. The standard doesn't say what destructors may or may not be called in this circumstance. – Feb 22 '17 at 17:02
-
-
Unfortunately this is from standard C++ point of view, but MS thinks differently: http://stackoverflow.com/questions/443147/c-mix-new-delete-between-libs – Slava Feb 22 '17 at 17:23
-
@Slava I expanded the answer a bit to consider language extensions in general. – eerorika Feb 22 '17 at 17:40
It depends on the version of the compiler and flags that dynamic library was compiled with.
The library's call to new
grabs the object from the heap controlled by the library.
Your call to delete
places the object back to the heap controlled by your executable.
This may or may not be the same heap managed by the same library.
The safe way is to wrap the delete
in the library call, like fopen/fclose.
-
Hearing a rumor about this is what prompted my question, actually. I'm interested to know whether this two-heaps behavior is only done by obscure OSes, or whether e.g. mainstream Linux distros do it. – Keith Russell Feb 22 '17 at 17:15
-
I saw it when dynamic library was compiled wit an older version of g++. It was all long ago, may be there is a better solution by now. In any case, think of executable compiled with g++ and library compiled with an Intel compiler :) – Feb 22 '17 at 17:21
-
There in no such thing as "heap controlled by the library" in Unix/Linux world. As OP question says gcc, which probably means Linux, this is not a problem. – Slava Feb 22 '17 at 17:28
-
@Slava At the very least, if the dynamic library was compiled with static C runtime, you'll have that situation. And even if the library links to C runtime dynamically, if the C runtime version of library is very old, it will not be able to share the executable's version. So you will have two different heap data structures. – Feb 22 '17 at 18:40
-
Yes, if it was allocated with new
, and if the library (or any other code) doesn't try to use the object after the delete.

- 41,598
- 9
- 101
- 157
-
1
-
-
If the destructor of the base class is not virtual, it will not call the destructor of the derived class when you delete the base pointer. – mch Feb 22 '17 at 16:59
-
Yes, but having a non-virtual dtor doesn't make delete any less safe. It might leak memory if you should be invoking the derived dtor, but that's it. – Emil Laine Feb 22 '17 at 17:03
-
1@tuple_cat standard doesn't guarantee that. A conforming compiler is free to launch nethack, for example. Or just crash. Or corrupt your data. – eerorika Feb 22 '17 at 17:04