函数返回后指向无效内容的指针寻址



我有一个问题,返回这个const指针。使用调试器显示,场景被正确导入并存储在可变场景中。返回scene后,scene所指向的内容丢失,无法被调用loadData()的类访问。

const aiScene* IOHandler::loadData(const std::string& pFile){
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFile(pFile,
    aiProcess_CalcTangentSpace      |
    aiProcess_Triangulate           |
    aiProcess_JoinIdenticalVertices |
    aiProcess_SortByPType);
    return scene;
}

(ImporteraiScene(struct)是assimp库的一部分,不能修改)

我假设场景存储在堆栈上,返回调用重置堆栈指针,内容丢失。如何在c++中处理这样的问题?

你忘记看文档了

场景由Importer拥有,因此当它超出范围时将被破坏。把importer.GetOrphanedScene()还给它,用完后记得把它删掉。

或者,您可以将导入器存储在更永久的地方;但是,如果您需要同时导入和使用多个场景,那么这可能不太好。

我的猜测是Assimp::Importer拥有ReadFile返回的资源,所以当importer超出范围时,资源(内存)被释放,并且您最终返回一个悬垂指针。您可以通过参数传递它,或者使它成为static,以便它在函数作用域之外持续存在,或者动态分配scene,复制ReadFile返回的内容-

const aiScene* scene = new aiScene(*importer.ReadFile(pFile,
aiProcess_CalcTangentSpace      |
aiProcess_Triangulate           |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType));

你误解了这个问题。问题不在于指针是本地的&被摧毁。问题是Assimp::Importer的析构函数会破坏指针指向的对象。由于Assimp::Importer对象在函数结束时被销毁,指针现在指向无效的内容。

为什么需要loadData函数?为什么不像这里建议的那样使用ReadFile - http://assimp.sourceforge.net/lib_html/usage.html

或者,您的问题的解决方案将是确保Importer对象不会超出作用域,直到您使用aiScene

一种可能的方法是——将Importer对象作为loadData方法的参数。

const aiScene* IOHandler::loadData(Assimp::Importer & importer, 
           const std::string& pFile)
{
          const aiScene* scene = importer.ReadFile(pFile,
          aiProcess_CalcTangentSpace        |
          aiProcess_Triangulate         |
          aiProcess_JoinIdenticalVertices |
          aiProcess_SortByPType);
     return scene;
}

调用代码应该是这样的。

{
    ........
    Assimp::Importer imp;
    const aiScene * p = loadData(imp, pFile);
    // use aiScene 
    ........
    // Importer object goes out of scope here.
}

最新更新