查看: 2926|回复: 8

请教:有关osgDB::writeNodeFile出现的异常

[复制链接]

该用户从未签到

发表于 2009-2-1 12:01:38 | 显示全部楼层 |阅读模式
按照array版主给我的提示,
创建一个四边形然后输出OSG文件的过程中,
在执行osgDB::writeNodeFile时抛出异常,
提示信息为:“vertexOut.exe 中的 0x0043f19c 处未处理的异常: 0xC0000005: 读取位置 0xfeeeff06 时发生访问冲突”
一直无法找到问题出处,无法输出文件。 请问这是我配置的问题吗,应该如何解决
我的程序如下:
  1. // Windows 头文件:
  2. #include <windows.h>

  3. // C 运行时头文件
  4. #include <stdlib.h>
  5. #include <tchar.h>

  6. //OSG库
  7. #include <osgDB/ReadFile>
  8. #include <osgViewer/Viewer>
  9. #include <osg/Node>
  10. #include <osg/Geode>
  11. #include <osg/Geometry>
  12. #include <osgDB/Registry>
  13. #include <osgDB/WriteFile>

  14. osg::ref_ptr<osg::Node> createSenseGraph();

  15. using std::endl;

  16. osg::ref_ptr<osg::Node> createSenseGraph();

  17. int APIENTRY _tWinMain(HINSTANCE hInstance,
  18.                      HINSTANCE hPrevInstance,
  19.                      LPTSTR    lpCmdLine,
  20.                      int       nCmdShow)
  21. {
  22. osg::Node *node=createSenseGraph().get();

  23. osgDB::writeNodeFile(*node,"C:\\a.osg");

  24. return 0;
  25. }


  26. osg::ref_ptr<osg::Node> createSenseGraph()
  27. {
  28. osg::ref_ptr<osg::Geometry> geom=new osg::Geometry();
  29. osg::ref_ptr<osg::Vec3Array> v=new osg::Vec3Array();
  30. geom->setVertexArray(v.get());
  31. v->push_back(osg::Vec3(-1.f,0.f,-1.f));
  32. v->push_back(osg::Vec3(1.f,0,-1.f));
  33. v->push_back(osg::Vec3(1.f,0,1.f));
  34. v->push_back(osg::Vec3(-1.f,0,1.f));

  35. osg::ref_ptr<osg::Vec4Array> c=new osg::Vec4Array();
  36. geom->setColorArray(c.get());
  37. geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

  38. c->push_back(osg::Vec4(1.f,0,0,1.f));
  39. c->push_back(osg::Vec4(0,1.f,0,1.f));
  40. c->push_back(osg::Vec4(0,0,1.f,1.f));
  41. c->push_back(osg::Vec4(1.f,1.f,1.f,1.f));

  42. osg::ref_ptr<osg::Vec3Array> n=new osg::Vec3Array();
  43. geom->setNormalArray(n.get());
  44. geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

  45. n->push_back(osg::Vec3(0,-1.f,0));
  46. geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));

  47. osg::ref_ptr<osg::Geode> geode=new osg::Geode();
  48. geode->addDrawable(geom.get());

  49. return geode.get();
  50. }
复制代码

[ 本帖最后由 array 于 2009-2-1 12:14 编辑 ]

该用户从未签到

 楼主| 发表于 2009-2-1 12:04:30 | 显示全部楼层
补充一下,有一行代码被论坛表情转义了,在这里重发一下
geom->addPrimitiveSet(new osg:: DrawArrays(osg:: PrimitiveSet:: QUADS,0,4));

该用户从未签到

发表于 2009-2-1 12:18:57 | 显示全部楼层
这里您犯了一个OSG开发时比较容易出现的错误,就是没能正确应用ref_ptr的功能。
要直接解决问题的话,把return geode.get() 改成return geode就可以了。

ref_ptr可以在一个指针的作用周期结束时自动将其释放(如果它没有被别的对象引用的话),而不必再使用delete删除指针对象。因此,这里您的geode变量在函数结尾时会被自动释放掉,而您使用get()返回的指针也就成了野指针,自然会出错。

此外论坛提供了添加程序代码的功能,在编辑帖子的时候可以在工具栏的最后一个看到。如果您要粘贴代码,请使用这个功能粘贴,不然的确会多出那些不利于理解的转义字符来;或者您可以直接在代码之前加上[ code],之后加上[ /code],(去掉空格)会自动将中间的内容转换成这个形式,没有转义字符的干扰:
  1. geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
复制代码

[ 本帖最后由 array 于 2009-2-1 12:24 编辑 ]

该用户从未签到

 楼主| 发表于 2009-2-1 14:19:27 | 显示全部楼层
受益了,非常感谢您的帮助

该用户从未签到

 楼主| 发表于 2009-2-1 14:26:01 | 显示全部楼层
修改完之后问题依旧....

该用户从未签到

发表于 2009-2-1 14:50:09 | 显示全部楼层
ref_ptr还是用下面的方式比较安全。函数返回值为ref_ptr的话,以前还是可行的,现在可能代码有些改变,不适合这么用了;而且这样的确对内存管理容易造成混乱。不过您产生错误的原因应该还是如上面我的回帖所述
  1. osg::Node* createSenseGraph()
  2. {
  3.     ...
  4.     return geode.release();
  5. }
复制代码

该用户从未签到

发表于 2009-2-1 15:17:56 | 显示全部楼层
斑竹说的没错!野指针问题
osg::Node* createSenseGraph()
{
    osg::Node * node=  new  osg::Node ;
   return node;
}
osg::ref_ptr<osg::node> node = createSenseGraph()

该用户从未签到

发表于 2009-2-1 15:18:44 | 显示全部楼层
不过我觉得第一次斑竹说的应该也没错阿,直接返回ref_ptr应该也可以吧

该用户从未签到

 楼主| 发表于 2009-2-1 16:03:06 | 显示全部楼层
感谢你们的帮助,现在问题已经解决了,
可能就是 运用超级指针产生的问题,改成版主最后所说的那样就没问题了
  1. osg::Node* createSenseGraph()
  2. {
  3.     ...
  4.     return geode.release();
  5. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表