Selaa lähdekoodia

fix memory leak during export

kimkulling 5 vuotta sitten
vanhempi
sitoutus
ccd13436da
2 muutettua tiedostoa jossa 94 lisäystä ja 88 poistoa
  1. 41 36
      code/M3D/M3DExporter.cpp
  2. 53 52
      code/M3D/M3DWrapper.cpp

+ 41 - 36
code/M3D/M3DExporter.cpp

@@ -189,42 +189,42 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
                     continue;
                 if (aiProps[k].pKey) {
                     switch (m3d_propertytypes[k].format) {
-                        case m3dpf_color:
-                            if (mat->Get(aiProps[k].pKey, aiProps[k].type,
-                                        aiProps[k].index, c) == AI_SUCCESS)
-                                addProp(&m3d->material[mi],
-                                        m3d_propertytypes[k].id, mkColor(&c));
-                            break;
-                        case m3dpf_float:
-                            if (mat->Get(aiProps[k].pKey, aiProps[k].type,
-                                        aiProps[k].index, f) == AI_SUCCESS)
-                                addProp(&m3d->material[mi],
-                                        m3d_propertytypes[k].id,
-                                        /* not (uint32_t)f, because we don't want to convert
+                    case m3dpf_color:
+                        if (mat->Get(aiProps[k].pKey, aiProps[k].type,
+                                    aiProps[k].index, c) == AI_SUCCESS)
+                            addProp(&m3d->material[mi],
+                                    m3d_propertytypes[k].id, mkColor(&c));
+                        break;
+                    case m3dpf_float:
+                        if (mat->Get(aiProps[k].pKey, aiProps[k].type,
+                                    aiProps[k].index, f) == AI_SUCCESS)
+                            addProp(&m3d->material[mi],
+                                    m3d_propertytypes[k].id,
+                                    /* not (uint32_t)f, because we don't want to convert
                                          * it, we want to see it as 32 bits of memory */
-                                        *((uint32_t *)&f));
-                            break;
-                        case m3dpf_uint8:
-                            if (mat->Get(aiProps[k].pKey, aiProps[k].type,
-                                        aiProps[k].index, j) == AI_SUCCESS) {
-                                // special conversion for illumination model property
-                                if (m3d_propertytypes[k].id == m3dp_il) {
-                                    switch (j) {
-                                        case aiShadingMode_NoShading: j = 0; break;
-                                        case aiShadingMode_Phong: j = 2; break;
-                                        default: j = 1; break;
-                                    }
+                                    *((uint32_t *)&f));
+                        break;
+                    case m3dpf_uint8:
+                        if (mat->Get(aiProps[k].pKey, aiProps[k].type,
+                                    aiProps[k].index, j) == AI_SUCCESS) {
+                            // special conversion for illumination model property
+                            if (m3d_propertytypes[k].id == m3dp_il) {
+                                switch (j) {
+                                case aiShadingMode_NoShading: j = 0; break;
+                                case aiShadingMode_Phong: j = 2; break;
+                                default: j = 1; break;
                                 }
-                                addProp(&m3d->material[mi],
-                                        m3d_propertytypes[k].id, j);
                             }
-                            break;
-                        default:
-                            if (mat->Get(aiProps[k].pKey, aiProps[k].type,
-                                        aiProps[k].index, j) == AI_SUCCESS)
-                                addProp(&m3d->material[mi],
-                                        m3d_propertytypes[k].id, j);
-                            break;
+                            addProp(&m3d->material[mi],
+                                    m3d_propertytypes[k].id, j);
+                        }
+                        break;
+                    default:
+                        if (mat->Get(aiProps[k].pKey, aiProps[k].type,
+                                    aiProps[k].index, j) == AI_SUCCESS)
+                            addProp(&m3d->material[mi],
+                                    m3d_propertytypes[k].id, j);
+                        break;
                     }
                 }
                 if (aiTxProps[k].pKey &&
@@ -292,8 +292,8 @@ void ExportSceneM3D(
 // Prototyped and registered in Exporter.cpp
 void ExportSceneM3DA(
         const char *,
-        IOSystem*,
-        const aiScene*,
+        IOSystem *,
+        const aiScene *,
         const ExportProperties *
 
 ) {
@@ -312,7 +312,9 @@ void ExportSceneM3DA(
 M3DExporter::M3DExporter(const aiScene *pScene, const ExportProperties *pProperties) :
         mScene(pScene),
         mProperties(pProperties),
-        outfile() {}
+        outfile() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 void M3DExporter::doExport(
@@ -352,6 +354,9 @@ void M3DExporter::doExport(
     // explicitly release file pointer,
     // so we don't have to rely on class destruction.
     outfile.reset();
+
+    M3D_FREE(m3d->name);
+    m3d->name = nullptr;
 }
 
 // ------------------------------------------------------------------------------------------------

+ 53 - 52
code/M3D/M3DWrapper.cpp

@@ -50,15 +50,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #ifdef ASSIMP_USE_M3D_READFILECB
 
-# if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
-#  define threadlocal thread_local
-# else
-#  if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
-#   define threadlocal __declspec(thread)
-#  else
-#   define threadlocal
-#  endif
-# endif
+#if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
+#define threadlocal thread_local
+#else
+#if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
+#define threadlocal __declspec(thread)
+#else
+#define threadlocal
+#endif
+#endif
 
 extern "C" {
 
@@ -66,37 +66,37 @@ extern "C" {
 threadlocal void *m3dimporter_pIOHandler;
 
 unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
-	ai_assert(nullptr != fn);
-	ai_assert(nullptr != size);
-	std::string file(fn);
-	std::unique_ptr<Assimp::IOStream> pStream(
-			(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
-	size_t fileSize = 0;
-	unsigned char *data = NULL;
-	// sometimes pStream is nullptr in a single-threaded scenario too for some reason
-	// (should be an empty object returning nothing I guess)
-	if (pStream) {
-		fileSize = pStream->FileSize();
-		// should be allocated with malloc(), because the library will call free() to deallocate
-		data = (unsigned char *)malloc(fileSize);
-		if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
-			pStream.reset();
-			*size = 0;
-			// don't throw a deadly exception, it's not fatal if we can't read an external asset
-			return nullptr;
-		}
-		pStream.reset();
-	}
-	*size = (int)fileSize;
-	return data;
+    ai_assert(nullptr != fn);
+    ai_assert(nullptr != size);
+    std::string file(fn);
+    std::unique_ptr<Assimp::IOStream> pStream(
+            (reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
+    size_t fileSize = 0;
+    unsigned char *data = NULL;
+    // sometimes pStream is nullptr in a single-threaded scenario too for some reason
+    // (should be an empty object returning nothing I guess)
+    if (pStream) {
+        fileSize = pStream->FileSize();
+        // should be allocated with malloc(), because the library will call free() to deallocate
+        data = (unsigned char *)malloc(fileSize);
+        if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
+            pStream.reset();
+            *size = 0;
+            // don't throw a deadly exception, it's not fatal if we can't read an external asset
+            return nullptr;
+        }
+        pStream.reset();
+    }
+    *size = (int)fileSize;
+    return data;
 }
 }
 #endif
 
 namespace Assimp {
 M3DWrapper::M3DWrapper() {
-	// use malloc() here because m3d_free() will call free()
-	m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
+    // use malloc() here because m3d_free() will call free()
+    m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
 }
 
 M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
@@ -105,41 +105,42 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
     }
 
 #ifdef ASSIMP_USE_M3D_READFILECB
-	// pass this IOHandler to the C callback in a thread-local pointer
-	m3dimporter_pIOHandler = pIOHandler;
-	m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
-	// Clear the C callback
-	m3dimporter_pIOHandler = nullptr;
+    // pass this IOHandler to the C callback in a thread-local pointer
+    m3dimporter_pIOHandler = pIOHandler;
+    m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
+    // Clear the C callback
+    m3dimporter_pIOHandler = nullptr;
 #else
-	m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
+    m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
 #endif
 }
 
 M3DWrapper::~M3DWrapper() {
-	reset();
+    reset();
 }
 
 void M3DWrapper::reset() {
-	ClearSave();
-	if (m3d_)
-		m3d_free(m3d_);
-	m3d_ = nullptr;
+    ClearSave();
+    if (m3d_) {
+        m3d_free(m3d_);
+    }
+    m3d_ = nullptr;
 }
 
 unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
 #if (!(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER))
-	ClearSave();
-	saved_output_ = m3d_save(m3d_, quality, flags, &size);
-	return saved_output_;
+    ClearSave();
+    saved_output_ = m3d_save(m3d_, quality, flags, &size);
+    return saved_output_;
 #else
-	return nullptr;
+    return nullptr;
 #endif
 }
 
 void M3DWrapper::ClearSave() {
-	if (saved_output_)
-		M3D_FREE(saved_output_);
-	saved_output_ = nullptr;
+    if (saved_output_)
+        M3D_FREE(saved_output_);
+    saved_output_ = nullptr;
 }
 } // namespace Assimp