【问题标题】:Segfault in shared_ptr destructorshared_ptr 析构函数中的段错误
【发布时间】:2018-09-24 16:08:23
【问题描述】:

上下文

我正在尝试制作一个小型游戏引擎,目前我正在开发一个实体组件系统。我有一组指向模型对象的共享指针(从 OBJ 文件读取的 3D 模型)。然后,我使用模型组件将模型与实体连接起来,该组件本质上具有两个数组的结构,一个带有实体句柄,另一个带有模型的索引。索引指的是组件中具有指向模型的实际共享指针的向量元素。我这样做是为了不必在动态分配的内存中构造共享指针。

我有两个模型类,基类Model 和一个专门的子类UntexturedModel,它以更有效的方式存储顶点位置数据。为了进行测试,我现在使用两个实体并将第一个实体分配给 Model 对象和另一个 UntexturedModel 对象(以确保两者在此系统中都能正常运行)。

问题

实际组件行为按预期工作,模型与实体正确连接并在渲染时检索。但是当main 函数终止时,就会出现段错误。我用 Valgrind 试图找出问题出在哪里,它说有一个来自std::default_delete<Model>::operator()(Model*) 的无效跳转。

我尝试创建一个完全相同类型的单独共享指针并立即重置它,AFAIK 应该会触发相同的问题,但它顺利通过。经过几个类似的测试(只使用基类模型,两个实体只使用一个模型,添加一个调用~Model然后删除指针的自定义删除器)我相当肯定问题只发生在main之后函数终止。

我可以添加任何代码sn-ps,只要问哪些。

【问题讨论】:

  • 不要只发布难以组合的小代码-sn-ps,请尝试创建一个Minimal, Complete, and Verifiable Example 来展示问题并且您可以向我们展示。简化不仅对我们有帮助,而且对您也有帮助。它甚至可能让您自己找到问题所在。
  • 与其发布sn-ps,如果您能找到minimal reproducible example,那将是最有帮助的。一种方法是将项目复制到其他地方,并开始尽可能多地提取不相关的代码,只要同样的问题仍然存在。
  • 您可能会遇到内存损坏,损坏的症状是 shared_ptr 析构函数中的段错误。时空分离的前因后果,让调试更有趣。
  • 另外,Valgrind 没说别的吗?任何地方都没有越界访问?构建时没有警告,即使启用更多警告也没有?

标签: c++ segmentation-fault destructor shared-ptr


【解决方案1】:

问题似乎是在main 函数之后试图删除Model 析构函数中的OpenGL 对象(VAO 和VBO),因为此时,OpenGL 上下文已经终止。通过将模型组件管理器放在唯一指针中并在主循环完成后但在 OpenGL 上下文终止之前重置它来强制销毁,不会导致更多的无效跳转。

感谢@Swift 为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多