代码之家  ›  专栏  ›  技术社区  ›  Andrew

一个简单的OpenGL程序内存泄漏

  •  1
  • Andrew  · 技术社区  · 15 年前

    我编写了一个简单的OpenGL程序来做一些测试。程序如下:

    #include <QApplication>
    #include <QGLWidget>
    #include <QTimer>
    #include <glut.h>
    
    class Ren : public QGLWidget
    {
    public:
     Ren() : QGLWidget() 
     {
      timer = new QTimer(this);
      connect(timer, SIGNAL(timeout()),
       this, SLOT(updateGL()));
     }
    
     void startUpdateTimer()
     {
      timer->start(40);
     }
    
     void initializeGL()
     {
      glShadeModel(GL_SMOOTH);      
      glClearColor(0.5f, 0.5f, 0.5f, 0.0f);     
      glClearDepth(1.0f);       
      glEnable(GL_DEPTH_TEST);   
     }
    
     void resizeGL(int width, int height)
     {
      if(height == 0){
       height = 1;
      }
      glViewport(0, 0, width, height);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      GLfloat aspectRatio = (GLfloat)width / (GLfloat)height;
      gluPerspective(60.0, aspectRatio, 0.01, 10000.0);
      glMatrixMode(GL_MODELVIEW);
     }
    
     void paintGL()
     {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
    
      gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);
    
      glColor3d(1, 0, 0);
      glutSolidCube(0.3);
     }
    
     QTimer *timer;
    };
    
    int main(int argc, char **argv)
    {
     QApplication app(argc, argv);
    
     Ren r;
     r.show();
     r.startUpdateTimer();
    
     return app.exec();
    }
    

    问题是,当计时器处于活动状态时,应用程序正在泄漏内存。 对于泄漏检测,我使用了Windows任务管理器。

    4 回复  |  直到 14 年前
        1
  •  3
  •   Patrice Bernassola    15 年前

    因为rend是一个子类,所以必须声明一个虚拟析构函数。否则,会出现内存泄漏,如果在将任对象用作qglobject时删除任对象,则会导致堆损坏。

    编辑 移除部分:

    在构造函数中,您正在为计时器分配内存,但从未释放它。您需要删除计时器指针。

        2
  •  0
  •   Andrew    15 年前

    对不起的。我错了。现在泄漏了。一段时间(大约一分钟)后,“泄漏”停止。我认为这是一种OpenGL或Qt工作。我查看了一些qt示例,并在纹理示例中看到了相同的内容。同样的事情也发生了,如果我在paintgl()函数中更改另一个例子来绘制其他的东西(取决于它有不同的“泄漏”时间)。

        3
  •  0
  •   WolfgangP    15 年前

    请详细说明您的程序泄漏了多少内存。我非常怀疑您的代码是否泄漏,因为您只是在分配 QTIMER对象。即使你不删除计时器,这也不是问题,因为操作系统还是会释放内存。当然,这很难看,但不是 泄漏 严格意义上说。

    如果分配的内存随时间稳定增长,则会出现内存泄漏。如果是这样的话,那不是你的代码的错误,因为你只需要分配一个计时器就可以了 一旦 .

        4
  •  0
  •   qlsbjlidrfgpu    14 年前

    GLUT原语应该用在运行GLUT主循环的GLUT程序中,该循环清除原语分配的四元,通过在GLUT程序外部调用GLUT原语,可以绕过清除任务,然后泄漏内存。

    如果你添加一个使用过的内存泄漏检测程序-在Windows上的Valgrind或Mac上的仪器-你会看到泄漏的块来自GlunewQuadric。 移除对glutsolidcude的调用,泄漏将消失。

    一个简单的解决方案是使用免费的GLUT原语,而不是整个GLUT随操作系统一起运送。

    推荐文章