I remember someone saying if you create a class through a lib you should destroy it through the lib. So does this mean i shouldnt call delete? i should call myclass.deleteMe() instead? would overloading delete solve the problem?
A problem with your application's deleting something that was created within a lib is that the lib might use a different heap/memory manager.
Solutions include:
- Ensure that your application is built with the same heap manager as the library.
- Implement a (non-inline) deleteMe method in the class, whose implementation can be
delete this;
- Define custom
operator delete
within the class, implemented within the library ... if there's a custom operator delete then it will called if and when your application delete an istance of the object.
I remember someone saying if you create a class through a lib you should destroy it through the lib.
That means if you call a function in a lib to create an object for you, you should read the documentation of that function, which must say how you free that object again. Often the function for free something is named similar to the allocation function. For example, the library pcre
has two functions called pcre_malloc
and pcre_free
.
The reason is, because the library allocates in a way opaque to you (which is the reason you use the function in the first place). It could get memory from the data-section of the program, while you would (wrongly) assume it got the memory possibly from the heap when using delete
.
If you are that library writer, the same rules apply. Make sure that when one of your functions return a object allocated dynamically, you say how the caller has to handle it
- Is the object encapsulated into a smart pointer? Then the smart pointer will take care of calling the appropriate deleter you designated.
- Do you return a raw pointer? You should avoid that, because the caller has to keep track of the pointer, and the caller will have to pass the pointer into a function you document in your interface. That's just another level of dependency you put on the burden of the user of your library, which smart pointers can elegantly rationalize away.
- Do you return an object by value, which by itself wraps an allocated resource? If that is the case, overload the copy constructor, copy assignment operator and destructor of that object's class, which then manages the resource by either copying it properly or sharing it among all other instances of its object (see this answer).
You should almost never overload the delete operator for your class unless you have also overloaded the new operator. Overloading the delete operator is not to be taking literally: It means you merely overload deallocation of the associated memory of an object. It only makes sense if you are housing your own memory pool or want to log every allocation/deallocation of memory for your objects.
This rule applies to the classes that You design. The rule of thumb (though not always used) is that if a class creates an object, it should delete it.
But if you are asking about some library that somebody else designed, you can't know, whether he obeyed this rule, and you have to check it through himselef / documentation / code.
You should consult the library's documentation for how to delete objects it creates. Besides what others have mentioned, sometimes a library has an expectation about when objects will be deleted. In wxWidgets for example, you shouldn't delete widgets yourself because wxWidgets will try to delete them for you when their parent widget is destroyed -- if you've already deleted them then you have a double free (undefined behavior). There is no way to determine this simply from looking at the types -- libraries may operate this way even if they don't return a smart pointer. Further, the library may depend on deallocations happening in a specific order (e.g. maybe it always deallocates all of one type of object before another), and deleting things yourself ruins the order.
If your library provides a specific method to construct objects, in terms of memory managers etc. then there should be no way for you to get rid of that object except through a meaningful manner that would dispose of the object in a similar manner to how it was constructed/allocated.
In other words, if your objects are prone to being allocated in a certain manner, make sure all ways to get rid of them follows your "certain manner".