Fix memory leak if nasal::Ghost creation fails

This commit is contained in:
Thomas Geymayer 2012-12-16 21:31:19 +01:00
parent ac27fae712
commit a1b7cb5330
2 changed files with 26 additions and 20 deletions

View File

@ -94,7 +94,7 @@ namespace nasal
*/
static T* createInstance(const T& ptr)
{
return new T(ptr);
return ptr ? new T(ptr) : 0;
}
static pointer getPtr(void* ptr)
@ -800,31 +800,32 @@ namespace nasal
static naRef makeGhost(naContext c, void *ptr)
{
if( !Ghost::getRawPtr(ptr) )
return naNil();
if( Ghost::getRawPtr(ptr) )
{
naGhostType* ghost_type = 0;
if( Ghost::returns_dynamic_type::value )
// For pointer policies already returning instances of an object
// with the dynamic type of this Ghost's raw_type the type is always
// the same.
ghost_type = &getSingletonPtr()->_ghost_type;
else
// If wrapping eg. shared pointers the users passes an already
// existing instance of an object which will then be hold be a new
// shared pointer. We therefore have to check for the dynamic type
// of the object as it might differ from the passed static type.
ghost_type = getTypeFor<Ghost>( Ghost::getRawPtr(ptr) );
naGhostType* ghost_type = 0;
if( Ghost::returns_dynamic_type::value )
// For pointer policies already returning instances of an object with
// the dynamic type of this Ghost's raw_type the type is always the
// same.
ghost_type = &getSingletonPtr()->_ghost_type;
else
// If wrapping eg. shared pointers the users passes an already
// existing instance of an object which will then be hold be a new
// shared pointer. We therefore have to check for the dynamic type
// of the object as it might differ from the passed static type.
ghost_type = getTypeFor<Ghost>( Ghost::getRawPtr(ptr) );
if( ghost_type )
return naNewGhost2(c, ghost_type, ptr);
}
if( !ghost_type )
return naNil();
return naNewGhost2(c, ghost_type, ptr);
destroyGhost(ptr);
return naNil();
}
static void destroyGhost(void *ptr)
{
delete (T*)ptr;
delete static_cast<T*>(ptr);
}
/**

View File

@ -45,6 +45,10 @@ typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
naRef member(Derived&, const nasal::CallContext&) { return naNil(); }
naRef f_derivedGetX(naContext c, const Derived& d)
{
return nasal::to_nasal(c, d.getX());
}
int main(int argc, char* argv[])
{
@ -104,6 +108,7 @@ int main(int argc, char* argv[])
Ghost<Derived>::init("Derived")
.bases<Base>()
.member("x", &Derived::getX, &Derived::setX)
.member("x_alternate", &f_derivedGetX)
.method_func<&member>("free_member");
naRef derived = Ghost<Derived>::create(c);