]> git.mxchange.org Git - simgear.git/commitdiff
Fix memory leak if nasal::Ghost creation fails
authorThomas Geymayer <tomgey@gmail.com>
Sun, 16 Dec 2012 20:31:19 +0000 (21:31 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sun, 16 Dec 2012 20:31:19 +0000 (21:31 +0100)
simgear/nasal/cppbind/Ghost.hxx
simgear/nasal/cppbind/cppbind_test.cxx

index d2a5d22c9906b80610750537961cb6f4720706ad..39b4f3c32be3aa6e501917c7c08a7df91b608310 100644 (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();
-
-        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::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 naNil();
+          if( ghost_type )
+            return naNewGhost2(c, ghost_type, ptr);
+        }
 
-        return naNewGhost2(c, ghost_type, ptr);
+        destroyGhost(ptr);
+        return naNil();
       }
 
       static void destroyGhost(void *ptr)
       {
-        delete (T*)ptr;
+        delete static_cast<T*>(ptr);
       }
 
       /**
index 47a437bcb01aa8dbd8f06240875df38422dbff38..d8b29b1b439cc9d35efce65e75ac41d3504b9440 100644 (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);