2 关于内存申请位置不对带来的野指针问题
2.1 问题描述:
resize(height() * 639 / 480, height());
QOsgWidget *bBoxEdit = new QOsgWidget(modelPath, static_cast<QWidget*>(this));
// use an ArgumentParser object to manage the program arguments.
bBoxEdit->pWidget = new osgQOpenGLWidget(&arguments, this);
bBoxEdit->pWidget->show();
// init the manipulators
bBoxEdit->InitManipulators();
bBoxEdit->InitModel(modelPath, bBoxEdit->mRoot);
// **************** part0: inside code segment of func call **********************/
osg::ref_ptr<osgViewer::Viewer> mViewer = bBoxEdit->pWidget->getOsgViewer();
// Add a Stats Handler to the viewer
mViewer->addEventHandler(new osgViewer::StatsHandler);
// Add the Camera to the Viewer
osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
// Set projection matrix and camera attribtues
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setClearColor(osg::Vec3f(0.2f, 0.2f, 0.4f, 1.0f));
//mViewer->addSlave(camera.get());
mViewer->setCamera(camera.get());
// Set the Scene Data
// *************************** part1: func call **********************************/
// bBoxEdit->InitCameraConfig();
如上代码段,是一段qt程序中,在MainWindow的一个子函数的一段代码,其中bBoxEdit是一个自定义的供调用的类,
问题来了, part0的代码就是把part2的代码拿出来,仅仅使用part1的代码就会出错,仅仅使用part2就不会,请推测原因?
这里给出part1的实现代码:
void QOsgWidget::InitCameraConfig() {
// Create the viewer for this window
mViewer = this->pWidget->getOsgViewer();
// Add a Stats Handler to the viewer
mViewer->addEventHandler(new osgViewer::StatsHandler);
// Add the Camera to the Viewer
osg::ref_ptr<osg::Camera> camera = mViewer->getCamera();
// Set projection matrix and camera attribtues
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setClearColor(osg::Vec3f(0.2f, 0.2f, 0.4f, 1.0f));
//mViewer->addSlave(camera.get());
mViewer->setCamera(camera.get());
// Add the Camera Manipulator to the Viewer
osg::ref_ptr<osgGA::TrackballManipulator> trackball = new osgGA::TrackballManipulator();
mViewer->setCameraManipulator(trackball.get());
// Set the Scene Data
mViewer->setSceneData(mRoot.get());
}
2.2 错误原因推测:
首先想到,这肯定是指针带来的问题,指针和作用域和代码范围息息相关,所以放到函数里面和放到mainwindow的一个子函数的随便的一处,最大的区别在于,
- 0 part2的情况:part2里面的函数调用所用到的指针,是存在qosgwidget的类的栈空间的,意味着只要类不析构,那么该指针所指向的内存就不会被回收。
- 1 part1的情况:part1里面申请的内存是在mainwindow的一个子函数调用里面申请的,意味着该指针,在该子函数调用结束,它指向的内存会被回收,倘若这一块内存里运行的函数是我们恰恰不希望他在函数结束后就消失,那么我们就需要把这个指针存在一个 ‘安全’ 的地方。所以你需要存在哪里? 因为上面可以知道,该指针的内存里的函数是被 qosgwidget这个类所需要的,也就是当这个类结束啦,这个指针才会被回收,所以我们把指针存在这里,就不会出现上面的问题了。
2.3 得出结论(个人观点)
cpp的内存管理问题:
- 0 尽量不要在业务流程里申请内存,释放内存,如果遇到需要申请内存和释放的地方,请把这一块儿写成一个类,
用类的变量来保存内存指针,用类的析构来释放内存。 - 1 重复1的观点:基于类作为内存管理的最小粒度,不要基于指针