2015-07-29 2 views
3

Недавно я передал свой игровой движок тесту на утечку памяти с valgrind; на самом деле мне сказали, что в моем классе Mesh просачивается ~ 7000 байтов; странная вещь заключается в том, что это говорит мне об этом:Assimp утечка памяти

7,280 bytes in 1 blocks are definitely lost in loss record 391 of 393 
==5639== at 0x4C2C100: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==5639== by 0x598647E: ??? (in /usr/lib/libassimp.so.3.0.1264) 
==5639== by 0x597F37D: ??? (in /usr/lib/libassimp.so.3.0.1264) 
==5639== by 0x58139E5: ??? (in /usr/lib/libassimp.so.3.0.1264) 
==5639== by 0x581E2B2: Assimp::Importer::ReadFile(char const*, unsigned int) (in /usr/lib/libassimp.so.3.0.1264) 
==5639== by 0x40D71A: glDetail::CMesh::CMesh(char const*) (Mesh.cpp:49) 
==5639== by 0x412FB5: _ZN9__gnu_cxx13new_allocatorIN8glDetail5CMeshEE9constructIS2_IRPKcEEEvPT_DpOT0_ (in /home/mattmatt/workspace/C++/alpha++/main-dev/eclipse/Alpha++/Debug/Alpha++) 

Так что вопрос: является ли Assimp ответственным за утечку памяти? Вот часть кода, который находится под вопросом:

CMesh::CMesh(const char* fileName){ 
    Assimp::Importer importer; 

    const aiScene* scene = importer.ReadFile(fileName, aiProcess_Triangulate | 
                 aiProcess_GenSmoothNormals | 
                 aiProcess_FlipUVs | 
                 aiProcess_CalcTangentSpace 
                 ); 
    if(!scene){ 
     LOG_ERROR("Mesh", "ERROR LOADING MESH ! : CHECK THE SUPPORTED MODEL TYPES MODEL I OR THE FILE PATH !"); 
     abort(); 
    } 
    const aiMesh* model = scene->mMeshes[0]; 

    std::vector<Vertex> vertices; 
    std::vector<unsigned int> indices; 

    const aiVector3D aiZeroVector(.0f, .0f, .0f); 
    IndexedModel out; 

    for(unsigned i = 0; i < model->mNumVertices; ++i) 
    { 
     const aiVector3D* pPos = &(model->mVertices[i]); 
     const aiVector3D* pNormal = &(model->mNormals[i]); 
     const aiVector3D* pTexCoord = model->HasTextureCoords(0) ? &(model->mTextureCoords[0][i]) : &aiZeroVector; 

     const aiVector3D* pTangent = &(model->mTangents[i]); 

     Vertex vert (
         glm::vec3(pPos->x, pPos->y, pPos->z),///positions 
         glm::vec2(pTexCoord->x, pTexCoord->y),///UV coords 
         glm::vec3(pNormal->x, pNormal->y, pNormal->z),///normals 
         glm::vec3(pTangent->x, pTangent->y, pTangent->z)///tangents 

        ); 

     vertices.push_back(vert); 

     out.positions.push_back(*vert.getPos()); 
     out.texCoords.push_back(*vert.getTexCoord()); 
     out.normals.push_back(*vert.getNormal()); 
     out.tangents.push_back(*vert.getTangent()); 
    } 
    for(unsigned i = 0; i < model->mNumFaces; ++i){ 
     const aiFace& face = model->mFaces[i]; 
     assert(face.mNumIndices == 3); 
     indices.push_back(face.mIndices[0]); 
     indices.push_back(face.mIndices[1]); 
     indices.push_back(face.mIndices[2]); 
    } 


    importer.FreeScene(); 

    out.indices = indices; 
    initMesh(out); 
} 

полный код для моего класса сетки можно посмотреть на этот вопрос Memory Leak in opengl Mesh class при необходимости :)

////////// ////////////////// Важное изменение ///////////////////////////

я выделил часть кода, которая просочилась ресурсы:

Assimp::Importer importer; 

     const aiScene* scene = importer.ReadFile("res/Suzy.obj", aiProcess_Triangulate | 
                  aiProcess_GenSmoothNormals | 
                  aiProcess_FlipUVs | 
                  aiProcess_CalcTangentSpace 
                  ); 
     if(!scene){ 
      LOG_ERROR("Mesh", "ERROR LOADING MESH ! : CHECK THE SUPPORTED MODEL TYPES MODEL I OR THE FILE PATH !"); 
      abort(); 
     } 

Что я должен изменить?

+1

Не используйте простые указатели. Использовать, например. 'unique_ptr', и проблема решится сама. –

+0

В моей библиотеке используются указатели, но затем обертывается все как shared_ptr пользователю; в чем была проблема? – Coder32

+0

[Документация] (http://assimp.sourceforge.net/lib_html/class_assimp_1_1_importer.html # a174418ab41d5b8bc51a044895cb991e5) функции'ReadFile' говорит: «Возвращенные данные предназначены только для чтения, объект-импортер сохраняет право собственности на данные и уничтожит его при уничтожении». Похоже, что код правильный. Возможно, это проблема с valgrind. –

ответ

1

В documentation of Importer::ReadFile(const char *, unsigned) состояния:

Если вызов успешен, содержимое файла возвращается как указатель на объект aiScene. Возвращенные данные предназначены для чтения только для чтения, объект-импортер сохраняет право собственности на данные и уничтожит его при уничтожении.

Исходя из этого, похоже, что вы используете библиотеку Assimp правильно, но проблема с утечкой памяти в самой библиотеке.

The ??? линии означает, что отладочная информация недоступна. Если это действительно настоящая утечка памяти, очень полезно иметь отладочную информацию, чтобы точно определить, где происходит утечка памяти. Отладочная информация особенно важна в этом случае, потому что Importer :: ReadFile() вызывает не виртуального участника BaseImporter::ReadFile(const Importer*, const std::string&, IOSystem*), который затем вызывает чисто виртуальный член BaseImporter::InternReadFile(const std::string&, aiScene*, IOSystem*). Я бы предположил, что 0x58139E5 является BaseImporter :: ReadFile(). Фреймы стека за пределами этого будут зависеть от того, какая реализация BaseImporter была выбрана Импортером :: ReadFile().

В системах Fedora отладочная информация может быть получена путем установки соответствующего debuginfo package, когда это возможно. Fedora предоставляет пакет assimp-DebugInfo, который может быть установлен с помощью:

 
sudo yum --enablerepo fedora-debuginfo,updates-debuginfo install assimp-debuginfo 

В системах Ubuntu и Debian, отладочная информация получается путем установки -dbg package при наличии. К сожалению, ни Debian 8 'Jessie', ни Ubuntu 15.04 'Vivid Vervet' не предлагают пакет libassimp-dbg.

Вы можете попробовать построить Assimp из источника с информацией об отладке. См. Вопрос «Переполнение стека» Creating symbol table for gdb using cmake для получения инструкций о том, как это сделать.

+0

Спасибо; так что я знаю, что могу продолжить свой проект :) – Coder32

+0

2) Я ** имею ** яркую vervet ... – Coder32

+0

@ Coder32: Рад, что я мог бы помочь. Я бы порекомендовал перестроить Assimp с отладочной информацией. В этом конкретном случае документация указывает, что ваше использование Assimp правильное и что сама библиотека протекает в памяти. В других случаях это может быть не так ясно. Наличие информации об отладке поможет вам определить, является ли утечка в Assimp проблемой утечки памяти в библиотеке, или если ваше приложение неправильно использует библиотеку или если оно ложно. –

1

Я тоже испытывал эти ошибки с SDL2 или opengl; Вы должны предположить, что официанты знают, что они делают; то же самое для opengl, glew и SDL2.

Смежные вопросы