I have an abstract class in my dll.
class IBase {
protected:
virtual ~IBase() = 0;
public:
virtual void f() = 0;
};
I want to get IBase in my exe-file which loads dll.
First way is to create following function
IBase * CreateInterface();
and to add the virtual function Release() in IBase.
Second way is to create another function
boost::shared_ptr<IBase> CreateInterface();
and no Release() function is needed.
Questions.
1) Is it true that the destructor and memory deallocation is called in the dll (not in exe-file) in the second case?
2) Does the second case work well if exe-file and dll was compiled with different compilers (or different settings).
An answer to your first question: The virtual destructor in your dll is called - the information about its location is embedded in your object (in the vtable). In the case of memory deallocation it depends how disciplined the users of your IBase are. If they know they have to call Release() and consider that exception can bypass the control flow in an surprising direction, the right one will be used.
But if CreateInterface() returns shared_ptr<IBase> it can bind the right deallocation function right to this smart pointer. Your library may look like this:
Destroy(IBase* p) {
... // whatever is needed to delete your object in the right way
}
boost::shared_ptr<IBase> CreateInterface() {
IBase *p = new MyConcreteBase(...);
...
return shared_ptr<IBase>(p, Destroy); // bind Destroy() to the shared_ptr
} // which is called instead of a plain
// delete
Thus every user of your DLL is easily prevented against resource leaks. They never have to bother about calling Release() or pay attention to exceptions bypassing surprisingly their control flow.
To answer your second question: The downside of this approach is clearly stated by the other answers: You're audience has to use the same compiler, linker, settings, libraries as you. And if they could be quite a lot this can be major drawback for your library. You have to choose: Safety vs. larger audience
But there's a possible loophole: Use shared_ptr<IBase>in your application, i.e.
{
shared_ptr<IBase> p(CreateInterface(), DestroyFromLibrary);
...
func();
...
}
Thus no implementation specific object is passed across the DLL boundary. Nevertheless your pointer is safely hidden behind the shared_ptr, who's calling DestroyFromLibrary at the right time even if func()'s throwing an exception or not.
I would advise against using shared_ptr in the interface. Even using C++ at all in the interface of a DLL (as opposed to "extern C" only routines) is problematic because name-mangling will prevent you from using the DLL with a different compiler. Using shared_ptr is particularly problematic because, as you have already identified, there is no guarantee that the client of the DLL will use the same implementation of shared_ptr as the caller. (This is because shared_ptr is a template class and the implementation is contained entirely in the header file.)
To answer your specific questions:
I'm not quite sure what you are asking here... I'm assuming that your DLL will contain implementations of classes derived from IBase. The code for their destructors (as well as the rest of the code) will, in both of your cases, be contained in the DLL. However, if the client initiates the destruction of the object (by calling delete in the first case or by letting the last instance of the shared_ptr go out of scope in the second case), then the destructor will be called from client code.
Name-mangling will usually prevent your DLL from being used with a different compiler anyway... but the implementation of shared_ptr may change even in a new release of the same compiler, and that can get you into trouble. I would shy away from using the second option.
Using shared_ptr will make sure the resource releasing function will be called in the DLL.
Have a look at the answers to this question.
A way out of this problem is to create a pure C interface and a thin fully inlined C++ wrapper around it.
On your first question: I'm taking an educated guess and not speaking from experience, but it seems to me that the second case the memory deallocation will be called "in the .exe". There are two things that happen when you call delete object;: first, destructors are called and second, the memory for the object is freed. The first part, destructor calling, will definitely work as you expect, calling the right destructors in your dll. However, since shared_ptr is class template, its destructor is generated in your .exe, and therefore it will call operator delete() in your exe and not the one in the .dll. If the two were linked against different runtime versions (or even statically linked against the same runtime version) this should lead to the dreaded undefined behavior (this is the part I'm not entirely sure about, but it seems logical to be that way). There's a simple way to verify if what I said is true - override the global operator delete in your exe, but not your dll, put a breakpoint in it and see what's called in the second case (I'd do that myself, but I have this much time for slacking off, unfortunately).
Note that the same gotcha exist for the first case (you seem to realize that, but just in case). If you do this in the exe:
IBase *p = CreateInterface();
delete p;
then you are in the same trap - calling operator new in the dll and calling operator delete in the exe. You'll either need a corresponding DeleteInterface(IBase *p) function in your dll or a Release() method in IBase (which doesn't have to be virtual, just not make it inline) for the sole purpose of calling the right memory deallocation function.
Related
In my solution I obtain several object pointers from dynamically loaded DLL through imported function:
DLL side
extern "C"
API_EXPORT PluginBase* createInstance(const string& typeName)
{
return TypeRegistry::instance().getTypeInstance(typeName);
}
Client side
HMODULE lib = LoadLibrary("theDll.dll");
void* proc = GetProcAddress(lib, "createInstance");
if(proc)
{
auto createFunc = reinterpret_cast<T* (*)(const string&)>(proc);
shared_ptr<PluginBase> instancePtr(createFunc(theType));
}
The actual question is what is considered more correct and/or more convenient?
To supply additional exported function like releaseInstance(PluginBase*) to DLL library and use it.
To delete instance pointer from the client code.
Regards
Provide the deleter.
It clears up any confusion about how the user is supposed to delete the object (delete? free (it comes from an extern "C" call after all)?)
And what's more, in some versions of Visual Studio, the way the runtime library works may, depending on the compiler options, mean that you cannot delete an object in one module that was newed in another.
Better than either option, though (IMO): return a shared_ptr that you already initialized with an appropriate deleter.
For good encapsulation/secret hiding I would prefer the first approach (i.e. provide a custom delete method). You gain more flexibility, e.g. if object creation is expensive, you might have some object pool from which the createInstance method returns a free object. Instead of actually deleting an object, a simple reset might be sufficient then on release.
Depending on your scenario it might be clear that you will never need something like this (and if you are using this method only at few places). Nevertheless, as it doesn't introduce a lot of complexity to have this encapsulation, I'd probably prefer that first approach in most situations.
The details of the creation is only known to the DLL.
The client can not know what they must do to properly dispose of the object.
It would be expected that the DLL will provide a means to properly dispose of the object, even if at the time of creation there is no special reason why the client should not delete it on its own.
The way of creating and disposing may change in the future and the client's code will break if it was not given a method to dispose the object in the early versions.
I've been thinking about the possible use of delete this in c++, and I've seen one use.
Because you can say delete this only when an object is on heap, I can make the destructor private and stop objects from being created on stack altogether. In the end I can just delete the object on heap by saying delete this in a random public member function that acts as a destructor. My questions:
1) Why would I want to force the object to be made on the heap instead of on the stack?
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Any scheme that uses delete this is somewhat dangerous, since whoever called the function that does that is left with a dangling pointer. (Of course, that's also the case when you delete an object normally, but in that case, it's clear that the object has been deleted). Nevertheless, there are somewhat legitimate cases for wanting an object to manage its own lifetime.
It could be used to implement a nasty, intrusive reference-counting scheme. You would have functions to "acquire" a reference to the object, preventing it from being deleted, and then "release" it once you've finished, deleting it if noone else has acquired it, along the lines of:
class Nasty {
public:
Nasty() : references(1) {}
void acquire() {
++references;
}
void release() {
if (--references == 0) {
delete this;
}
}
private:
~Nasty() {}
size_t references;
};
// Usage
Nasty * nasty = new Nasty; // 1 reference
nasty->acquire(); // get a second reference
nasty->release(); // back to one
nasty->release(); // deleted
nasty->acquire(); // BOOM!
I would prefer to use std::shared_ptr for this purpose, since it's thread-safe, exception-safe, works for any type without needing any explicit support, and prevents access after deleting.
More usefully, it could be used in an event-driven system, where objects are created, and then manage themselves until they receive an event that tells them that they're no longer needed:
class Worker : EventReceiver {
public:
Worker() {
start_receiving_events(this);
}
virtual void on(WorkEvent) {
do_work();
}
virtual void on(DeleteEvent) {
stop_receiving_events(this);
delete this;
}
private:
~Worker() {}
void do_work();
};
1) Why would I want to force the object to be made on the heap instead of on the stack?
1) Because the object's lifetime is not logically tied to a scope (e.g., function body, etc.). Either because it must manage its own lifespan, or because it is inherently a shared object (and thus, its lifespan must be attached to those of its co-dependent objects). Some people here have pointed out some examples like event handlers, task objects (in a scheduler), and just general objects in a complex object hierarchy.
2) Because you want to control the exact location where code is executed for the allocation / deallocation and construction / destruction. The typical use-case here is that of cross-module code (spread across executables and DLLs (or .so files)). Because of issues of binary compatibility and separate heaps between modules, it is often a requirement that you strictly control in what module these allocation-construction operations happen. And that implies the use of heap-based objects only.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Well, your use-case is really just a "how-to" not a "why". Of course, if you are going to use a delete this; statement within a member function, then you must have controls in place to force all creations to occur with new (and in the same translation unit as the delete this; statement occurs). Not doing this would just be very very poor style and dangerous. But that doesn't address the "why" you would use this.
1) As others have pointed out, one legitimate use-case is where you have an object that can determine when its job is over and consequently destroy itself. For example, an event handler deleting itself when the event has been handled, a network communication object that deletes itself once the transaction it was appointed to do is over, or a task object in a scheduler deleting itself when the task is done. However, this leaves a big problem: signaling to the outside world that it no longer exists. That's why many have mentioned the "intrusive reference counting" scheme, which is one way to ensure that the object is only deleted when there are no more references to it. Another solution is to use a global (singleton-like) repository of "valid" objects, in which case any accesses to the object must go through a check in the repository and the object must also add/remove itself from the repository at the same time as it makes the new and delete this; calls (either as part of an overloaded new/delete, or alongside every new/delete calls).
However, there is a much simpler and less intrusive way to achieve the same behavior, albeit less economical. One can use a self-referencing shared_ptr scheme. As so:
class AutonomousObject {
private:
std::shared_ptr<AutonomousObject> m_shared_this;
protected:
AutonomousObject(/* some params */);
public:
virtual ~AutonomousObject() { };
template <typename... Args>
static std::weak_ptr<AutonomousObject> Create(Args&&... args) {
std::shared_ptr<AutonomousObject> result(new AutonomousObject(std::forward<Args>(args)...));
result->m_shared_this = result; // link the self-reference.
return result; // return a weak-pointer.
};
// this is the function called when the life-time should be terminated:
void OnTerminate() {
m_shared_this.reset( NULL ); // do not use reset(), but use reset( NULL ).
};
};
With the above (or some variations upon this crude example, depending on your needs), the object will be alive for as long as it deems necessary and that no-one else is using it. The weak-pointer mechanism serves as the proxy to query for the existence of the object, by possible outside users of the object. This scheme makes the object a bit heavier (has a shared-pointer in it) but it is easier and safer to implement. Of course, you have to make sure that the object eventually deletes itself, but that's a given in this kind of scenario.
2) The second use-case I can think of ties in to the second motivation for restricting an object to be heap-only (see above), however, it applies also for when you don't restrict it as such. If you want to make sure that both the deallocation and the destruction are dispatched to the correct module (the module from which the object was allocated and constructed), you must use a dynamic dispatching method. And for that, the easiest is to just use a virtual function. However, a virtual destructor is not going to cut it because it only dispatches the destruction, not the deallocation. The solution is to use a virtual "destroy" function that calls delete this; on the object in question. Here is a simple scheme to achieve this:
struct CrossModuleDeleter; //forward-declare.
class CrossModuleObject {
private:
virtual void Destroy() /* final */;
public:
CrossModuleObject(/* some params */); //constructor can be public.
virtual ~CrossModuleObject() { }; //destructor can be public.
//.... whatever...
friend struct CrossModuleDeleter;
template <typename... Args>
static std::shared_ptr< CrossModuleObject > Create(Args&&... args);
};
struct CrossModuleDeleter {
void operator()(CrossModuleObject* p) const {
p->Destroy(); // do a virtual dispatch to reach the correct deallocator.
};
};
// In the cpp file:
// Note: This function should not be inlined, so stash it into a cpp file.
void CrossModuleObject::Destroy() {
delete this;
};
template <typename... Args>
std::shared_ptr< CrossModuleObject > CrossModuleObject::Create(Args&&... args) {
return std::shared_ptr< CrossModuleObject >( new CrossModuleObject(std::forward<Args>(args)...), CrossModuleDeleter() );
};
The above kind of scheme works well in practice, and it has the nice advantage that the class can act as a base-class with no additional intrusion by this virtual-destroy mechanism in the derived classes. And, you can also modify it for the purpose of allowing only heap-based objects (as usually, making constructors-destructors private or protected). Without the heap-based restriction, the advantage is that you can still use the object as a local variable or data member (by value) if you want, but, of course, there will be loop-holes left to avoid by whoever uses the class.
As far as I know, these are the only legitimate use-cases I have ever seen anywhere or heard of (and the first one is easily avoidable, as I have shown, and often should be).
The general reason is that the lifetime of the object is determined by some factor internal to the class, at least from an application viewpoint. Hence, it may very well be a private method which calls delete this;.
Obviously, when the object is the only one to know how long it's needed, you can't put it on a random thread stack. It's necessary to create such objects on the heap.
It's generally an exceptionally bad idea. There are a very few cases- for example, COM objects have enforced intrusive reference counting. You'd only ever do this with a very specific situational reason- never for a general-purpose class.
1) Why would I want to force the object to be made on the heap instead of on the stack?
Because its life span isn't determined by the scoping rule.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
You use delete this when the object is the best placed one to be responsible for its own life span. One of the simplest example I know of is a window in a GUI. The window reacts to events, a subset of which means that the window has to be closed and thus deleted. In the event handler the window does a delete this. (You may delegate the handling to a controller class. But the situation "window forwards event to controller class which decides to delete the window" isn't much different of delete this, the window event handler will be left with the window deleted. You may also need to decouple the close from the delete, but your rationale won't be related to the desirability of delete this).
delete this;
can be useful at times and is usually used for a control class that also controls the lifetime of another object. With intrusive reference counting, the class it is controlling is one that derives from it.
The outcome of using such a class should be to make lifetime handling easier for users or creators of your class. If it doesn't achieve this, it is bad practice.
A legitimate example may be where you need a class to clean up all references to itself before it is destructed. In such a case, you "tell" the class whenever you are storing a reference to it (in your model, presumably) and then on exit, your class goes around nulling out these references or whatever before it calls delete this on itself.
This should all happen "behind the scenes" for users of your class.
"Why would I want to force the object to be made on the heap instead of on the stack?"
Generally when you force that it's not because you want to as such, it's because the class is part of some polymorphic hierarchy, and the only legitimate way to get one is from a factory function that returns an instance of a different derived class according to the parameters you pass it, or according to some configuration that it knows about. Then it's easy to arrange that the factory function creates them with new. There's no way that users of those classes could have them on the stack even if they wanted to, because they don't know in advance the derived type of the object they're using, only the base type.
Once you have objects like that, you know that they're destroyed with delete, and you can consider managing their lifecycle in a way that ultimately ends in delete this. You'd only do this if the object is somehow capable of knowing when it's no longer needed, which usually would be (as Mike says) because it's part of some framework that doesn't manage object lifetime explicitly, but does tell its components that they've been detached/deregistered/whatever[*].
If I remember correctly, James Kanze is your man for this. I may have misremembered, but I think he occasionally mentions that in his designs delete this isn't just used but is common. Such designs avoid shared ownership and external lifecycle management, in favour of networks of entity objects managing their own lifecycles. And where necessary, deregistering themselves from anything that knows about them prior to destroying themselves. So if you have several "tools" in a "toolbelt" then you wouldn't construe that as the toolbelt "owning" references to each of the tools, you think of the tools putting themselves in and out of the belt.
[*] Otherwise you'd have your factory return a unique_ptr or auto_ptr to encourage callers to stuff the object straight into the memory management type of their choice, or you'd return a raw pointer but provide the same encouragement via documentation. All the stuff you're used to seeing.
A good rule of thumb is not to use delete this.
Simply put, the thing that uses new should be responsible enough to use the delete when done with the object. This also avoids the problems with is on the stack/heap.
Once upon a time i was writing some plugin code. I believe i mixed build (debug for plugin, release for main code or maybe the other way around) because one part should be fast. Or maybe another situation happened. Such main is already released built on gcc and plugin is being debugged/tested on VC. When the main code deleted something from the plugin or plugin deleted something a memory issue would occur. It was because they both used different memory pools or malloc implementations. So i had a private dtor and a virtual function called deleteThis().
-edit- Now i may consider overloading the delete operator or using a smart pointer or simply just state never delete a function. It will depend and usually overloading new/delete should never be done unless you really know what your doing (dont do it). I decide to use deleteThis() because i found it easier then the C like way of thing_alloc and thing_free as deleteThis() felt like the more OOP way of doing it
I'm playing around with C++/CLI, using the MSDN documentation and the ECMA standard, and Visual C++ Express 2010. What struck me was the following departure from C++:
For ref classes, both the finalizer and destructor must be written so they can be executed multiple times and on objects that have not been fully constructed.
I concocted a little example:
#include <iostream>
ref struct Foo
{
Foo() { std::wcout << L"Foo()\n"; }
~Foo() { std::wcout << L"~Foo()\n"; this->!Foo(); }
!Foo() { std::wcout << L"!Foo()\n"; }
};
int main()
{
Foo ^ r;
{
Foo x;
r = %x;
} // #1
delete r; // #2
}
At the end of the block at #1, the automatic variable xdies, and the destructor is called (which in turn calls the finalizer explicitly, as is the usual idiom). This is all fine and well. But then I delete the object again through the reference r! The output is this:
Foo()
~Foo()
!Foo()
~Foo()
!Foo()
Questions:
Is it undefined behavior, or is it entirely acceptable, to call delete r on line #2?
If we remove line #2, does it matter that r is still a tracking handle for an object that (in the sense of C++) no longer exists? Is it a "dangling handle"? Does its reference counting entail that there will be an attempted double deletion?
I know that there isn't an actual double deletion, as the output becomes this:
Foo()
~Foo()
!Foo()
However, I'm not sure whether that's a happy accident or guaranteed to be well-defined behaviour.
Under which other circumstances can the destructor of a managed object be called more than once?
Would it be OK to insert x.~Foo(); immediately before or after r = %x;?
In other words, do managed objects "live forever" and can have both their destructors and their finalizers called over and over again?
In response to #Hans's demand for a non-trivial class, you may also consider this version (with destructor and finalizer made to conform to the multiple-call requirement):
ref struct Foo
{
Foo()
: p(new int[10])
, a(gcnew cli::array<int>(10))
{
std::wcout << L"Foo()\n";
}
~Foo()
{
delete a;
a = nullptr;
std::wcout << L"~Foo()\n";
this->!Foo();
}
!Foo()
{
delete [] p;
p = nullptr;
std::wcout << L"!Foo()\n";
}
private:
int * p;
cli::array<int> ^ a;
};
I'll just try to address the issues you bring up in order:
For ref classes, both the finalizer and destructor must be written so they can be executed multiple times and on objects that have not been fully constructed.
The destructor ~Foo() simply auto-generates two methods, an implementation of the IDisposable::Dispose() method as well as a protected Foo::Dispose(bool) method which implements the disposable pattern. These are plain methods and therefore may be invoked multiple times. It is permitted in C++/CLI to call the finalizer directly, this->!Foo() and is commonly done, just like you did. The garbage collector only ever calls the finalizer once, it keeps track internally whether or not that was done. Given that calling the finalizer directly is permitted and that calling Dispose() multiple times is allowed, it is thus possible to run the finalizer code more than once. This is specific to C++/CLI, other managed languages don't allow it. You can easily prevent it, a nullptr check usually gets the job done.
Is it undefined behavior, or is it entirely acceptable, to call delete r on line #2?
It is not UB and entirely acceptable. The delete operator simply calls the IDisposable::Dispose() method and thus runs your destructor. What you do inside it, very typically calling the destructor of an unmanaged class, may well invoke UB.
If we remove line #2, does it matter that r is still a tracking handle
No. Invoking the destructor is entirely optional without a good way to enforce it. Nothing goes wrong, the finalizer ultimately will always run. In the given example that will happen when the CLR runs the finalizer thread one last time before shutting down. The only side effect is that the program runs "heavy", holding on to resources longer than necessary.
Under which other circumstances can the destructor of a managed object be called more than once?
It's pretty common, an overzealous C# programmer may well call your Dispose() method more than once. Classes that provide both a Close and a Dispose method are pretty common in the framework. There are some patterns where it is nearly unavoidable, the case where another class assumes ownership of an object. The standard example is this bit of C# code:
using (var fs = new FileStream(...))
using (var sw = new StreamWriter(fs)) {
// Write file...
}
The StreamWriter object will take ownership of its base stream and call its Dispose() method at the last curly brace. The using statement on FileStream object calls Dispose() a second time. Writing this code so that this doesn't happen and still provide exception guarantees is too difficult. Specifying that Dispose() may be called more than once solves the problem.
Would it be OK to insert x.~Foo(); immediately before or after r = %x;?
It's okay. The outcome is unlikely to be pleasant, a NullReferenceException would be the most likely result. This is something that you should test for, raise an ObjectDisposedException to give the programmer a better diagnostic. All standard .NET framework classes do so.
In other words, do managed objects "live forever"
No, the garbage collector declares the object dead, and collects it, when it cannot find any references to the object anymore. This is a fail-safe way to memory management, there is no way to accidentally reference a deleted object. Because doing so requires a reference, one that the GC will always see. Common memory management problems like circular references are not an issue either.
Code snippet
Deleting the a object is unnecessary and has no effect. You only delete objects that implement IDisposable, an array does not do so. The common rule is that a .NET class only implements IDisposable when it manages resources other than memory. Or if it has a field of a class type that itself implements IDisposable.
It is furthermore questionable whether you should implement a destructor in this case. Your example class is holding on to a rather modest unmanaged resource. By implementing the destructor, you impose the burden on the client code to use it. It strongly depends on the class usage how easy it is for the client programmer to do so, it definitely is not if the object is expected to live for a long time, beyond the body of a method so that the using statement isn't usable. You can let the garbage collector know about memory consumption that it cannot track, call GC::AddMemoryPressure(). Which also takes care of the case where the client programmer simply doesn't use Dispose() because it is too hard.
Guidelines from standard C++ still apply:
Calling delete on an automatic variable, or one that's already been cleaned up, is still a bad idea.
It's a tracking pointer to a disposed object. Dereferencing such is a bad idea. With garbage collection, the memory is kept around as long as any non-weak reference exists, so you can't access the wrong object by accident, but you still can't use this disposed object in any useful way, since its invariants probably no longer hold.
Multiple destruction can only happen on managed objects when your code is written in really bad style that would have been UB in standard C++ (see 1 above and 4 below).
Explicitly calling the destructor on an automatic variable, then not creating a new one in its place for the automatic destruction call to find, is still a bad idea.
In general, you think think of object lifetime as separate from memory allocation (just like standard C++ does). Garbage collection is used to manage deallocation -- so the memory is still there -- but the object is dead. Unlike standard C++, you can't go and reuse that memory for raw byte storage, because parts of the .NET runtime may assume the metadata is still valid.
Neither the garbage collector nor "stack semantics" (automatic variable syntax) use reference counting.
(Ugly details: disposing an object doesn't break the .NET runtime's own invariants concerning that object, so you can probably even still use it as a threading monitor. But that just makes an ugly hard-to-understand design, so please don't.)
I have a function foo() in dll A.dll, whose definition is as follows
vector<CustomObject> foo()
{
vector<CustomObject> customObjectCollection;
//code which populates customObjectCollection goes here
return customObjectCollection;
}
I am referring this method vector foo() of dll A from exe B
When i make a call to the function foo from B, I get an unhandled exception which says
"unhandled exception at
0x10487b3f(msvcp90d.dll) in B.exe"
0xC0000005: Access violation while
writing to the location 0xfdfdfdfd".
Note:type CustomObject does not implement copy constructor
When i tried to debug by attaching B.exe to A.dll, I found that inside method vector foo(), the vector gets populated without any problem but when the control returns to B.exe the valves in vector doesnot get copied !!!
Also, if method foo returns vector by reference , exception doesnot occur and B.exe receives an empty vetor.
what is the issue ?? Is it happening as I have not implemented copy constructor for CustomObject.
Any help is greatly appreciated
(Apologies for not articulating the question properly)
Thanks
jeel
This is a classic symptom of mismatched runtime libraries. You have to make sure that both the EXE and the DLL are linked to the dynamic C++ library (DLL version).
If one (or both) are linked with the static C++ runtime (LIB version), you'll get memory violations since there will be two instances of the runtime library with different address spaces.
First of all you should not return references to local objects declared on stack.
Second: there are requirements for elements to be able to be used in STL containers
1) Copy constructor
2) Assignment operator
3) Public destructor
There are more container specific (like sorting criterium for associative containers).
Copy constructor will be created as well as assignment operator (thanks to the compiler) so unless you explicitly hide them - your object has them (if you did not have copy constructor, compiler would complain).
But these implicit copy constructor and assignment operator may not be smart enough, so you may want to implement your own. For instance: lets say that you CustomObject in constructor creates an instance of some class with new and keep it as pointer to be destroyed in the destructor. Default copy constructor will make a shallow copy, so this will result in two objects holding the same pointer. Once one of them is destroyed, second one becomes inconsistent (it holds pointer that has already been released).
Final note: try not to return vector by value. A lot of copying is involved. Declare it in the caller on stack and pass it as reference to you foo.
Probably the safest way would be:
bool foo(vector<someclass*> &customObjectCollection)
{
//code which populates customObjectCollection goes here
return success
}
This way the calling program creates and maintains the vector so there's no need for copying. Caller would do
vector<someclass *> customObjectCollection;
foo(customObjectCollection);
Also, depending on what you are doing exactly, note the use of a vector of someclass pointers rather than someclass objects.
There are a number of possibilities here, and you haven't told us enough to determine which is most likely to apply.
One possibility is (semi-)unique to putting the code in a DLL. If you link the standard library statically, each module (EXE, DLL) gets its own memory management, including its own heap, so quite a few operations that try to transfer ownership of memory between one module and another will fail for (seemingly) strange reasons. The cure for this type of problem is usually to link to the standard library in a DLL for all your modules. This gives one copy of the standard library shared throughout the application, so passing ownership between modules doesn't cause a problem.
Another possibility is that your CustomObject class isn't handling copying appropriately. Since you've told us nothing about its internals, it's impossible for us to guess what you might need to do here.
I have a Windows DLL that at one point, returns a pointer to a class that is new'ed in the DLL's code. The class itself is a very thin wrapper around another class private to the DLL.
The calling executable has no problem working with this class, everything works fine, with the exception that when the calling executable tries to delete this class, I get a RtlValidateHeap error.
The reasons behind the error makes sense, the exe is trying to free memory on the DLL's heap, which is normally a bad thing.
I've come up with a few possible solutions:
Override the class's new operator to
allocate its memory off of the
executable's heap (provided I can
even get at that heap space). The wrapper is very thin, so I would only be allocating a few bytes from the exe's heap.
Provide a special destruction
function for this class (yuck).
Tell the user not to destroy the
class and live with leaks (no way!)
Is there a 'normal' way of doing this?
Most libraries that use this sort of functionality, whether C or C++, actually go with your second option - specific functions to get and release objects. It allows distribution of binary DLLs that don't have to be compiled identically to the calling executable.
I've seen this behaviour is when one of the binaries was built with debug options (which uses a debug heap that, amongst other things, uses RtlValidateHeap) and the other binary was built as a release binary. It might be worth checking that you only use like with like...
By far the easiest solution is (for the Visual Studio users) to use /MD or /MDd everywhere. If the CRT itself is in a DLL, there's only one heap. Your app and your DLL will share it.
Are you loading the DLL dynamically at runtime (by calling LoadLibrary), or are you linking to using a .lib file during the link phase of your exe? If you're dynamically loading/unloading the DLL then when the delete happens is the DLL still loaded? This is a classic problem for plug-in type designs and the typical solution is something like your second proposal - specific functions to create and delete the objects in question.
Option 2 is pretty normal, eg, a Release() method that just does a "delete this".
Note that normally the DLL doesn't have it's own heap as such - most DLLs will share the process heap (see GetProcessHeap), but often the language runtime will decorate or add padding around allocated memory - so the pointer your dll ends up with is not the same pointer the heap will expect in a call to free.
The general rule is always release allocated memory with the matching free function, from within the same module.
There are some exceptions though - memory you know has been allocated directly with HeapAlloc from a known heap can be freed from another module. GlobalAlloc/GlobalFree works across modules. Strings allocated with SysAllocString can be freed from another module. Memory you know has been allocated by the same DLL version of the runtime can be freed from another module, but I'd stay away from this.
On the DLL side, I would use something along these lines:
dll.h: /* all exported, included by dll user */
class dll_class {
public:
virtual void foo() = 0;
}
dll_class* create_class();
void delete_class(dll_class*);
dll.cpp: /* implement the creator and destroyer */
dll_class* create_class() { return new dll_class_imp(); }
void delete_class(dll_class* pClass) { delete pClass; }
dll_imp.h: /* implement the actual dll_class logic */
class dll_class_imp : public dll_class {
public:
virtual void foo() {...}
}
Now, on the DLL user's side, dll.h will be included, and used like so:
dll_class* pClass = create_class();
pClass->foo();
delete_class(pClass);
this way, there's a clear distinction between the DLL's part and the user's part. Being an abstract class, the user cannot create a dll_class using new; and it only makes sense you delete object similarly to the way you've created them, i.e. with the exported functions.
What looks like will work for us was to override the new and delete operators for the problem class. It turned out that there were 3 situations that could happen:
EXE new's object, EXE delete's object
DLL new's object, DLL delete's object
DLL new's object, EXE delete's object
The new and delete operators ensure that the DLL would be allocating and freeing all memory allocations. So far, so good - testing shows that the operators are always being used and the memory is coming from the DLL's heap.