首页 > 代码库 > OSG 智能指针陷阱
OSG 智能指针陷阱
先看下这个代码,有什么问题:
#include <osg/Group> #include <osg/Node> #include <osg/Geode> osg::Geode *geode= NULL; osg::ref_ptr<osg::Group> root = NULL; void createNode(){ geode = new osg::Geode; geode->setName("Hello"); root = new osg::Group; root->addChild(geode); } void GetNodeFromRoot(osg::Node ** node){ for(int i = 0; i<root->getNumChildren(); ++i) { if(root->getChild(i)->getName().compare("Hello") == 0) { osg::Node * tmp = root->getChild(i); root->removeChild(tmp); *node = tmp;//在这里tmp 已经析构,因为 只有root引用了hello节点,而在root 节点removechild后 tmp的引用计数为0,此时将析构 } } } int main() { createNode(); osg::Node * node = NULL; GetNodeFromRoot(&node); }
所以在最后得到的这个指针是个无效的指针。
正确的方法应该是:
void GetNodeFromRoot(osg::ref_ptr<osg::Node> & node) { for(int i = 0; i<root->getNumChildren(); ++i) { if(root->getChild(i)->getName().compare("Hello") == 0) { osg::Node * tmp = root->getChild(i); node = tmp;//要先让node对象对hello节点引用 root->removeChild(tmp); } } }
还有一种情况容易出问题:
#include <osg/Group> #include <osg/Node> #include <osg/Geode> int main() { osg::Geode * geode = new osg::Geode; int num = geode->referenceCount();//num 应该为0 { osg::ref_ptr<osg::Group> root =new osg::Group; root->addChild(geode); num = geode->referenceCount();//num 应该为1 } num = geode->referenceCount();//num 应该为 无效数字,因为此时geode已经析构 return 0; }
另一种常见的错误为 直接返回智能指针对象:
osg::Node * getNode() { osg::ref_ptr<osg::Geode> geode = new osg::Geode; return geode;//错误,应该为geode.release(); }
总结:
1. 在osg::ref_ptr<osg::Node>node = new osg::Node; 其中node 为osg::ref_ptr的对象,而不是指针。
2. OSG 中新创建的场景对象建议使用ref_ptr 进行内存分配和管理
3. 对于不使用ref_ptr 的对象,引用计数值变得没有意义,并且它无法自动从场景中卸载。
4. 新建对象作为函数结果返回时,应该返回release()。并尽快引入到别的场景中,否则发生内存泄露
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。