Overview
Features
Download
Documentation
Community
Add-Ons & Services

Abstract and Dynamic Factories destroy instances

General discussion regarding the development of POCO for contributors.

Abstract and Dynamic Factories destroy instances

Postby gregoire » 17 Mar 2009, 18:38

Currently the creation of objects is managed by the Factory via the createInstance method.
I was wondering if the deletion of this object should not be carried out by the Factory too, so that creation and deletion are managed in the same compilation unit, to avoid problems when linking to a dynamic library (in a plugin system for example).

So my question is:
Code: Select all
//Is it safer to do :
Base* b = myInstantiator.createInstance();
delete b;

//or
Base* b = myInstantiator.createInstance();
myInstantiator.destroyInstance(b);
gregoire
 
Posts: 30
Joined: 27 Jan 2009, 19:23
Location: Grenoble, France

Re: Abstract and Dynamic Factories destroy instances

Postby alex » 17 Mar 2009, 21:00

gregoire wrote:I was wondering if the deletion of this object should not be carried out by the Factory too, so that creation and deletion are managed in the same compilation unit, to avoid problems when linking to a dynamic library (in a plugin system for example).


This is a concern only if you are mixing different MSVC compiler versions (or mix release and debug code) - then you end up with different heaps for the DLLs. Even if we were to provide destroy() methods for all classes potentially affected by this, what are we to do with shared pointers? The only solution, then, remains having everything compiled with the same compiler.
alex
 
Posts: 1048
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Abstract and Dynamic Factories destroy instances

Postby chrisjones » 18 Mar 2009, 12:14

This is a concern only if you are mixing different MSVC compiler versions (or mix release and debug code) - then you end up with different heaps for the DLLs. Even if we were to provide destroy() methods for all classes potentially affected by this, what are we to do with shared pointers? The only solution, then, remains having everything compiled with the same compiler.

Can't that be solved using the SharedPtr release policy template parameter?
chrisjones
 
Posts: 35
Joined: 28 Jan 2008, 22:01
Location: United_Kingdom

Re: Abstract and Dynamic Factories destroy instances

Postby alex » 18 Mar 2009, 14:01

chrisjones wrote:Can't that be solved using the SharedPtr release policy template parameter?


There's two things you're dealing with here: allocation and deallocation. ReleasePolicy only addresses the latter. It does not guarantee where the pointer was allocated. You'd have to turn SharedPtr into a factory and ban users from using new.
alex
 
Posts: 1048
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Abstract and Dynamic Factories destroy instances

Postby chrisjones » 18 Mar 2009, 15:32

There's two things you're dealing with here: allocation and deallocation. ReleasePolicy only addresses the latter. It does not guarantee where the pointer was allocated. You'd have to turn SharedPtr into a factory and ban users from using new.

Isn't that up to the programmer? If your designing your application to new and delete in the same module then SharedPtr doesn't have to guarantee where it will be allocated. Factories create the instances, they should probably be able to destroy them too.

What about compiling as static libraries and using the static runtime (rather than the DLL version)? Doesn't that give different heaps meaning you must allocate and deallocate in the same module?
chrisjones
 
Posts: 35
Joined: 28 Jan 2008, 22:01
Location: United_Kingdom

Re: Abstract and Dynamic Factories destroy instances

Postby alex » 18 Mar 2009, 17:24

chrisjones wrote:Isn't that up to the programmer? If your designing your application to new and delete in the same module then SharedPtr doesn't have to guarantee where it will be allocated. Factories create the instances, they should probably be able to destroy them too.


I was not arguing whether a factory that returns pointer to heap-allocated memory should or not have a destroy() member. I do not even disagree that it would make sense that it does. My point was that new/delete across DLL boundaries is a tough problem to solve and introducing said member function is not enough to solve it. What are we, e.g., to do with Notifications where the recipient is responsible for freeing the memory by design?

chrisjones wrote:What about compiling as static libraries and using the static runtime (rather than the DLL version)? Doesn't that give different heaps meaning you must allocate and deallocate in the same module?


Same as with DLLs - if you are mixing binaries linked with different runtime library versions ("versions" as in 7.1, 8.0 etc as well as release/debug or single/multi-threaded), you will have different heaps. See this MSDN blog post.
alex
 
Posts: 1048
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Abstract and Dynamic Factories destroy instances

Postby gregoire » 18 Mar 2009, 19:57

I am building a plugin system:
do I have to force everybody that might develop plugins to use the same version of MSVC ?
or
if by design plugins are responsible of new/delete operations on the classes they add to my Factory, can I let them use the one they want (with same compiling options: \MD, etc) ?
gregoire
 
Posts: 30
Joined: 27 Jan 2009, 19:23
Location: Grenoble, France

Re: Abstract and Dynamic Factories destroy instances

Postby alex » 18 Mar 2009, 20:53

gregoire wrote:I am building a plugin system:
do I have to force everybody that might develop plugins to use the same version of MSVC ?


As things currently stand, yes. Either that or you and your users must be very careful not to new/delete across library boundaries. If you ask for advice, I'd force users to compile with same version of MSVC or, if that is not reasonable to expect, then you provide them with POCO binaries compiled with different MSVC versions/options so they can choose the ones matching their environment.

gregoire wrote:if by design plugins are responsible of new/delete operations on the classes they add to my Factory, can I let them use the one they want (with same compiling options: \MD, etc) ?


I'm not quite clear what do you mean by "add to my Factory". Factory is supposed to produce objects and is typically responsible to call new.

With regards to memory management, if you can assure that there is absolutely no new-ing in one module and delete-ing in another, it does not matter - you can mix and match modules at will. For as long as new and delete are called in the same module they are dealing with the same heap. Once you split them and cross the module boundary (i.e. call new in one module and delete in another) all modules must be linked against the same runtime or else you will have undefined behavior. IMO, containment of new/delete within a module will be very hard to achieve so I recommend using the same runtime and same version of MSVC compiler as the safest strategy.

To elaborate a bit (Guenter please comment if you are following) I've looked into what we have and as it currently stands, SharedPtr will call delete in client's module (ReleasePolicy is a template in header), while AutoPtr will call delete in Foundation (RefCountedObject::release() is defined in implementation file). If we are to eliminate naked pointers from the interfaces in 1.4, it could be beneficial to unify this by defining RefCountedObject in the header. Still, though, this would not eliminate but only alleviate the problem by making it less likely to happen. To entirely shield ourselves from this problem, designs like the one for Notifications, where framework is passing both pointers and responsibility to release the memory between clients (which may be in different modules), should be addressed. One scenario could be banning new/delete and naked pointers altogether, provide allocation/deallocation within the framework (i.e. inside smart pointers, which can not be templates) and require all POCO libraries to be linked against the same runtime. There may be some things eluding me at the moment, but I don't think this goal is worth pursuing (i.e. feasible).
alex
 
Posts: 1048
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Abstract and Dynamic Factories destroy instances

Postby guenter » 18 Mar 2009, 21:24

Dynamic memory is not your only problem when developing a plugin system in C++. ABI compatibility is another major issue if you're going to pass STL objects, or generally, C++ objects across borders. Also, as soon as you start to pass std::strings or other STL objects around, you have to be very careful, as to control the memory allocations/deallocations that might happen in them.
guenter
 
Posts: 1092
Joined: 11 Jul 2006, 16:27
Location: Austria


Return to Contributors

Who is online

Users browsing this forum: No registered users and 1 guest

cron