I have passed as callback a C++ member function to a C# project through a C++/CLI wrapper (this works fine). The C# project is going to call this delegate when receiving data from another .exe process: an event will be raised and a method will call this callback. So, I needed to "save" this Action delegate using an static instance of a C# class already created. I got the following code:
// C++ unmanaged function
WRAPPER_API void dispatchEvent(std::function<void(int)> processEvent)
{
Iface::Wrapper wrapper;
wrapper.callback = &processEvent;
wrapper.PassCallback();
}
//C++ Managed
public ref class Wrapper
{
public:
std::function<void(int)>* callback;
void ReturnToCallback(int data)
{
(*callback)(data);
}
void PassCallback()
{
StartGenerator^ startGen = gcnew StartGenerator(gcnew Action<int>(this, &Wrapper::ReturnToCallback));
}
};
// C#
public class StartGenerator
{
private Communication comm;
public StartGenerator(Action<int> callback)
{
comm = Communication.Instance;
comm.callback = callback;
}
}
If I call the Action delegate in StartGenerator method, the C++ function is properly executed. However, my goal was saving the delegate to be able to call it afterwards, when data is received from another .exe process. When this data arrives, an event is raised and callback is called from the event method. It is at this point when I get the following exception:
Unhandled Exception: System.AccessViolationException: Attempted to
read or write protected memory. This is often an indication that other
memory is corrupt. at
Iface.Wrapper.ReturnToCallback(Int32 data)
I think I need to manage the lifetime of the std::function, I don't know about the lifetime of the function object being pointed to by the managed class. The object seems to be deleted and the managed class is left holding a dangling pointer.
I think I need to manage the lifetime of the std::function
Yes, I told you as much when I told you to store a pointer in the managed wrapper, here
I don't know about the lifetime of the function object being pointed to by the managed class.
The std::function is a native object and follows the native C++ rules. Putting a pointer in a managed wrapper won't make it garbage-collected.
The object seems to be deleted and the managed class is left holding a dangling pointer.
Yes, your terminology isn't exact but you've correctly diagnosed the problem. Take a look:
void dispatchEvent(std::function<void(int)> processEvent)
{
Iface::Wrapper wrapper;
wrapper.callback = &processEvent;
wrapper.PassCallback();
}
processEvent is function argument, a std::function object passed by value. The copy made and stored in the argument lives until the end of scope. It has automatic storage duration. When the function returns, all the local variables, function arguments included, are destroyed (not "deleted").
You will need to dynamically allocate (a copy of) the std::function object, like:
typedef std::function<void(int)> cbfn;
wrapper.callback = new cbfn(processEvent);
Now you have a memory leak, but at least you aren't using the object after it's destroyed. If you only make a handful of these objects the leak might even be acceptable. In general, you should implement IDisposable on your wrapper and have the Dispose method do delete callback;. In C++/CLI you use destructor syntax to accomplish that.
~Wrapper()
{
delete callback;
callback = nullptr;
}
Related
The following observer class registers a callback function with a subject via a call to attach when its ctor executes. I would like the observer's dtor to unregister the callback function.
How do I pass the same pointer to detach as I did to attach so that the subject can remove it from its list of observers?
I'm thinking I have to store a shared_ptr to this but I'm not sure how I get from that to the shared_ptr to the member function callback.
Can anyone help?
Observer::Observer(Subject& subject) : m_subject(subject),
{
m_subject.attach("cmd", std::make_shared<std::function<void()>>(std::bind(&Observer::callback, this)));
}
Observer::~Observer()
{
// I tried this initially but realised that the pointer below
// is different to the one passed to `attach` from the ctor.
m_subject.detach("cmd", std::make_shared<std::function<void()>>(std::bind(&Observer::callback, this)));
}
void Observer::callback()
{
// do some stuff
}
attach and detach are declared as follows:
void Subject::attach(const std::string& command, const std::shared_ptr<std::function<void()>>& callback);
void Subject::detach(const std::string& command, const std::shared_ptr<std::function<void()>>& callback);
I would suggest to also store a copy of the shared_ptr in your observer class, as a member perhaps. Then you could you it to give the same pointer to detach.
Like this:
class Observer {
//Other Stuff here
private:
std::shared_ptr<std::function<void()>> callback_ptr;
};
Observer::Observer(Subject& subject) :
m_subject(subject),
callback_ptr(std::make_shared<std::function<void()>>(std::bind(&Observer::callback, this))
{
m_subject.attach("cmd", std::make_shared<std::function<void()>>(std::bind(&Observer::callback, this)));
}
Observer::~Observer()
{
m_subject.detach("cmd", callback_ptr));
}
It's worth noting that, as #dkg also mentioned, make_shared does always return a new shared_ptr for every time it's called, because it's purpose is to "create a new object with the following parameters and return a shared_ptr to it". Is roughly equivalent to shared_ptr(new std::function<void()> (std::bind(&Observer::callback, this)).
The reason why there is an extra make_shared function is to minimize allocations and to guarantee exception safety in a long expression.
If you just want to shared one object, then just distribute a copy of your shared_ptr.
Each time you call std::make_shared it allocates and constructs a new object for you.
In your code, you call it twice, then you have two instances of your object that are not the same.
You could call it once and keep the shared pointer as a member of your class.
I have used Luabind to bind a class to Lua. I need to make sure the class is correctly disposed of when it is destructed or made null through myClass = nil.
This class adds itself to a static list inside itself like this:
template<typename T>
class component : public componentInterface
{
public:
static std::list<componentInterface *> list;
component() : componentInterface()
{
di::component<T>::list.push_back(this);
}
~component()
{
di::component<T>::list.remove(this);
}
};
And when the destructor is called it promptly removes itself from the list.
You don't have to do anything. So long as Lua is creating the object, or Lua has adopted the object, Luabind will make sure that the destructor will be called.
However, Lua is garbage collected. This means that the destructor will not necessarily be called immediately after the last reference to the object is removed. Indeed, Lua can wait essentially indefinitely, until the actual lua_State object is released.
If more immediacy is important to you, then you can do one of the following:
Have a dispose method on the object that Lua can call to destroy it early. It is therefore Lua's responsibility to not use the object after making this call.
Execute the garbage collector by calling collectgarbage, so that the garbage is collected.
I know Java but don't have much knowledge of C++. I am trying to write a class for the first 3 statements in main function of the code at https://developers.google.com/v8/get_started.
First I have questions about how objects are created in C++. See the below code.
HandleScope handle_scope;
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
I think in C++ when you declare a variable of a class an instance of the class created at the point. You do not need to use new keyword like in Java. So the first statement would create an instance of HandleScope which will be stored in handle_scope.
Now I do not understand how the second statement would work. With my knowledge the part before = will create a new Persistent object which can be referred by the variable context. Then Context::New() will create a new object and store it in context? Huh, I know I am wrong. But I simply dont get how it would work?
I am trying to write a C++ class for the above. Here is my attempt.
class MyClass {
private:
HandleScope handle_scope;
Persistent<Context> context;
Context::Scope context_scope;
public:
MyClass();
};
MyClass::MyClass()
{
context = Context::New();
context_scope = new Context::Scope(context);
}
Have I done the initialization properly?
EDIT: Reply to peachykeen (in comments)
I did the following experimentation.
I wrote a Test class as below.
Test
{
public:
Test() {
cout << "Test" << endl;
}
};
In the main function I wrote Test test; It outputs "Test" which means an object is created without using new keyword.
You are right, in C++, objects are created as soon as they're defined. You do not need to use the new keyword.
However, unlike in Java, objects can be created with different kinds of duration. Using new creates an object on the heap, with dynamic storage duration: the variable lives until you explicitly delete it. (And new returns a pointer to the created object, so that you can track it)
If you simply define an object, as in your first and third lines, then it is created with automatic storage duration: that is, the object exists until it goes out of scope.
This means that you can create objects inside a function, and be guaranteed that they'll be destroyed as soon as you leave the function -- regardless of how you leave the function. Whether you return, or throw an exception, all objects with automatic storage duration (created without using new) are guaranteed to be properly cleaned up.
This means that you should always avoid new whenever possible. If you have to use new, you should typically wrap the resulting pointer into a smart pointer class, an object created with automatic storage duration, so that it gets destroyed automatically). The smart pointer will then call delete on the new-allocated object automatically, ensuring, again, that you don't leak memory.
This distinction is a very powerful tool, which good C++ programmers need to understand well. It is a key to avoiding memory leaks, or more generally, resource leaks of all kinds, and it is, in some respects, more powerful than Java's garbage collector.
For example, say we wish to open a file, and then write some data to it. In C++, we can do it like this:
void foo() {
std::ofstream file("foo.txt");
doStuff(file); // call a function which does something with the file
}
And because file was declared without using new, because it has automatic storage duration, we are guaranteed that it will have its destructor invoked when it goes out of scope, and it will be properly cleaned up -- that is, the stream will be flushed, and the file handle will be closed.
It doesn't matter if doStuff might throw an exception. No matter how we leave foo, file will be properly destroyed, so we don't need to mess about with try/finally like you would in Java. The class is exception-safe by itself, without requiring any additional effort from the user.
Try writing a similar snippet in Java, one which guarantees that even if doStuff throws an exception, the file will be immediately closed. It'll be much longer, and requires more care on the part of the user.
Persistent<Context> context = Context::New();
create object of type Persistent<Context>, initialized from returned of Context::New, if c-tor is not explicit.
Simple example.
#include <iostream>
class C
{
public:
C(int)
{
std::cout << "C::C(int)" << std::endl;
}
};
int main()
{
C c = 1;
}
your class should be
class MyClass {
private:
HandleScope handle_scope;
Persistent<Context> context;
Context::Scope context_scope;
public:
MyClass();
};
MyClass::MyClass():context(Context::New()),
context_scope(Context::Scope(context))
{
}
if Context::Scope is not pointer.
This would be the equivalent class:
class MyClass {
private:
HandleScope handle_scope;
Persistent<Context> context;
Context::Scope context_scope;
public:
MyClass();
};
MyClass::MyClass()
: context(Context::New()),
context_scope(context)
{
}
When you write a statement like this:
Persistent<Context> context = Context::New();
You are constructing context using the copy constructor. This is different from creating the object and then assigning a new value, although the result might often be equivalent.
Likewise this statement:
Context::Scope context_scope(context);
is constructing context_scope and passing context to the constructor. You get the equivalent behavior in a class using the constructor initializer syntax as in my example.
To create an instance of an object, you need only this: Type name; The newkeyword creates a pointer to an object. Normally, to initialize the object, we use parenthesis: Type name(parameter); Sometimes, when an object supports copying, you can use a function that returns an object and assign it to that object: Type name = Some_function_that_returns_Type(); You can now use name like any other object. If you say Type name = new Type;, you will get a compiler error. The keyword new returns a pointer. It would be correct to say Type * name = new Type;. (Note the *, saying that it is a pointer to a Type class, named name. When I refer to Type it is any object, such as your HandleScope. When I refer to name, it is the new object you are creating. The all of all is this: new is a completely different keyword that refers to pointers. If you are not using pointers, don't use it. Use the basic format Type name(parameter, another_param);.
I'm creating a wrapper for a HANDLE that does not work with DuplicateHandle, so instead I am trying to wrap the handle in a shared_ptr.
Imagine the following code:
class CWrapper
{
public:
CWrapper() :
m_pHandle(new HANDLE, &CWrapper::Close)
{
//code to open handle
}
private:
void Close()
{
//code to close handle
}
std::shared_ptr<HANDLE> m_pHandle;
}
I have also tried creating close with a HANDLE parameter (not ideal). Either way, I get the compiler error "Term does not evaluate to a function taking 0 arguments". Is this because of the implicit this pointer? How do I fix this? How do I call a member function from the shared pointer?
You can't call a member function but you can use a custom deleter that is a global function like so:
void my_deleter(Foo *ptr)
{
delete ptr;
std::cout<< "using custom deleter" <<std::endl;
}
shared_ptr<Foo> pf (new Foo, my_deleter);
I think you have your abstractions the wrong way around.
shared_ptr gives you a copyable "handle" to a shared resource that can't itself be copied. Using shared_ptr with a type that doesn't perform its own cleanup when it is deleted isn't an optimal use.
If make your class' single responsibility to clean up this inherently non-copyable resource properly in its destructor, then you can use shared_ptr to provide shared ownership which is what its single responsibility should be. (I consider HANDLE to be non-copyable as if you try to make a simple copy of a HANDLE the copies cannot be treated as independent; the last copy must be correctly closed so the owners of copies would need to know about other copies in existence.)
class CWrapper
{
public:
CWrapper()
{
// code to open handle
}
~CWrapper()
{
// code to close handle
}
private:
// prevent copying
CWrapper(const CWrapper&);
CWrapper& operator=(const CWrapper&);
HANDLE mHandle;
};
Now use shared_ptr<CWrapper> where you need to shared the handle, you can use a typedef if you think that this is too verbose.
A custom deleter is an overly complex solution, IMHO.
If you need to access non-static members from within Close you need to bind its this argument properly
CWrapper() :
m_pHandle(new HANDLE, boost::bind(&CWrapper::Close, this, _1)) {
//code to open handle
}
This, however contains a hidden bug. Your object is copyable, and you bind the deleter to the object of *this. The handle is associated with the first wrapper you create, but if you copy the wrapper, the handle is shared but associated with the first wrapper, which may not exist anymore:
CWrapper getWrapper() { CWrapper w; return w; }
CWrapper x = getWrapper();
After that code was executed and x is going to be destroyed, behavior is undefined because x's destruction of the internal handle pointer will try to use the object bound in w's constructor invokation - however that object doesn't exist anymore!
A solution to this can be to store the data associated with the handle in the allocated object itself, instead of trying to store it in the toplevel handle object, like in the following code
class CWrapper
{
public:
CWrapper():m_pHandle(new CHandle)
{ }
private:
// This class cannot be copied
class CHandle : boost::noncopyable {
friend class CWrapper;
CHandle()
:m_pHandle(new HANDLE) {
// code to open handle
}
~CHandle() {
// code to close this handle, making use of
// auxilary data for whatever reason
}
private:
boost::scoped_ptr<HANDLE> m_pHandle;
// auxilary data associated with the handle...
};
boost::shared_ptr<CHandle> m_pHandle;
};
The auxilary data is not not stored in the handle anymore, but together with the data that's shared among all copy of the wrapper. The shared data itself is created and destroyed using its normal constructor and destructor.
CWrapper getHandle() { return myHandle; }
CWrapper w = getHandle();
The last wrapper going out of life will destroy the handle, which is explicitly shared among all wrappers.
I haven't tested it, but based on the idea presented by shoosh, you may be able to pass a member function like this:
void Class::myDeleteMember(Foo *ptr)
{
delete ptr;
std::cout<< "using custom deleter" <<std::endl;
}
shared_ptr<Foo> pf (new Foo, boost::bind(&Class::myDeleteMember, _1));
Look for deleter in boost::shared_ptr docs. I couldn't find a direct link to it, but basically it is a functor that is called when the ref is 0.
I have objects which create other child objects within their constructors, passing 'this' so the child can save a pointer back to its parent. I use boost::shared_ptr extensively in my programming as a safer alternative to std::auto_ptr or raw pointers. So the child would have code such as shared_ptr<Parent>, and boost provides the shared_from_this() method which the parent can give to the child.
My problem is that shared_from_this() cannot be used in a constructor, which isn't really a crime because 'this' should not be used in a constructor anyways unless you know what you're doing and don't mind the limitations.
Google's C++ Style Guide states that constructors should merely set member variables to their initial values. Any complex initialization should go in an explicit Init() method. This solves the 'this-in-constructor' problem as well as a few others as well.
What bothers me is that people using your code now must remember to call Init() every time they construct one of your objects. The only way I can think of to enforce this is by having an assertion that Init() has already been called at the top of every member function, but this is tedious to write and cumbersome to execute.
Are there any idioms out there that solve this problem at any step along the way?
Use a factory method to 2-phase construct & initialize your class, and then make the ctor & Init() function private. Then there's no way to create your object incorrectly. Just remember to keep the destructor public and to use a smart pointer:
#include <memory>
class BigObject
{
public:
static std::tr1::shared_ptr<BigObject> Create(int someParam)
{
std::tr1::shared_ptr<BigObject> ret(new BigObject(someParam));
ret->Init();
return ret;
}
private:
bool Init()
{
// do something to init
return true;
}
BigObject(int para)
{
}
BigObject() {}
};
int main()
{
std::tr1::shared_ptr<BigObject> obj = BigObject::Create(42);
return 0;
}
EDIT:
If you want to object to live on the stack, you can use a variant of the above pattern. As written this will create a temporary and use the copy ctor:
#include <memory>
class StackObject
{
public:
StackObject(const StackObject& rhs)
: n_(rhs.n_)
{
}
static StackObject Create(int val)
{
StackObject ret(val);
ret.Init();
return ret;
}
private:
int n_;
StackObject(int n = 0) : n_(n) {};
bool Init() { return true; }
};
int main()
{
StackObject sObj = StackObject::Create(42);
return 0;
}
Google's C++ programming guidelines have been criticized here and elsewhere again and again. And rightly so.
I use two-phase initialization only ever if it's hidden behind a wrapping class. If manually calling initialization functions would work, we'd still be programming in C and C++ with its constructors would never have been invented.
Depending on the situation, this may be a case where shared pointers don't add anything. They should be used anytime lifetime management is an issue. If the child objects lifetime is guaranteed to be shorter than that of the parent, I don't see a problem with using raw pointers. For instance, if the parent creates and deletes the child objects (and no one else does), there is no question over who should delete the child objects.
KeithB has a really good point that I would like to extend (in a sense that is not related to the question, but that will not fit in a comment):
In the specific case of the relation of an object with its subobjects the lifetimes are guaranteed: the parent object will always outlive the child object. In this case the child (member) object does not share the ownership of the parent (containing) object, and a shared_ptr should not be used. It should not be used for semantic reasons (no shared ownership at all) nor for practical reasons: you can introduce all sorts of problems: memory leaks and incorrect deletions.
To ease discussion I will use P to refer to the parent object and C to refer to the child or contained object.
If P lifetime is externally handled with a shared_ptr, then adding another shared_ptr in C to refer to P will have the effect of creating a cycle. Once you have a cycle in memory managed by reference counting you most probably have a memory leak: when the last external shared_ptr that refers to P goes out of scope, the pointer in C is still alive, so the reference count for P does not reach 0 and the object is not released, even if it is no longer accessible.
If P is handled by a different pointer then when the pointer gets deleted it will call the P destructor, that will cascade into calling the C destructor. The reference count for P in the shared_ptr that C has will reach 0 and it will trigger a double deletion.
If P has automatic storage duration, when it's destructor gets called (the object goes out of scope or the containing object destructor is called) then the shared_ptr will trigger the deletion of a block of memory that was not new-ed.
The common solution is breaking cycles with weak_ptrs, so that the child object would not keep a shared_ptr to the parent, but rather a weak_ptr. At this stage the problem is the same: to create a weak_ptr the object must already be managed by a shared_ptr, which during construction cannot happen.
Consider using either a raw pointer (handling ownership of a resource through a pointer is unsafe, but here ownership is handled externally so that is not an issue) or even a reference (which also is telling other programmers that you trust the referred object P to outlive the referring object C)
A object that requires complex construction sounds like a job for a factory.
Define an interface or an abstract class, one that cannot be constructed, plus a free-function that, possibly with parameters, returns a pointer to the interface, but behinds the scenes takes care of the complexity.
You have to think of design in terms of what the end user of your class has to do.
Do you really need to use the shared_ptr in this case? Can the child just have a pointer? After all, it's the child object, so it's owned by the parent, so couldn't it just have a normal pointer to it's parent?