0

我正在使用 Visual Studio 2008,开发 OpenGL 窗口。我创建了几个用于创建骨架的类,一个用于关节,一个用于皮肤,一个用于 Body(它是多个关节和皮肤的支架),一个用于读取 skel/skin 文件。

在我的每个类中,我对大部分数据都使用了指针,其中大部分是使用 = new int[XX] 声明的。我为每个使用 delete[XX] 删除指针的类都有一个析构函数。

在我的 GLUT 显示函数中,我让它声明一个主体,打开文件并绘制它们,然后在显示结束时删除主体。但是程序中的某个地方仍然存在内存泄漏。随着时间的推移,它的内存使用量只会以一致的速度不断增加,我将其解释为不会被删除的东西。

我不确定是否是 glut 显示功能中的某些内容只是不删除 Body 类,还是其他内容。我已经按照 Visual Studio 2008 中的内存泄漏检测步骤进行操作,它没有报告任何泄漏,但我不能 100% 确定它是否适合我。我对 C++ 不流利,所以可能有些东西我忽略了,有人能看到吗?

从主要:

void display(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    Body *body = new Body();
    body->readSkel("C:\\skel2.skel");
    body->drawBody();
    body = new Body();
    body->readSkel("C:\\skel1.skel");
    body->drawBody();
    glutSwapBuffers();  
    body->~Body();
    delete body;
}

从身体:

Body::Body(){
    skelFile = string();
    skinFile = string();
    totalJoints = 0;
    joints = new Joint[25];
    skin = new Skin;
}

Body::~Body(){
    delete[25] joints;
    delete skin; 
}
4

4 回答 4

5

在这段代码中:

Body *body = new Body();
body->readSkel("C:\\skel2.skel");
body->drawBody();
body = new Body();

您正在泄漏 aBody因为您没有删除第一个。

还有这个:

body->~Body();
delete body;

很奇怪。您不会像那样显式调用析构函数 -delete负责调用析构函数。

这段代码:

delete[25] joints;

也很奇怪。正确的形式是:

delete [] joints;

您使用的是非标准语法,25将被忽略。有关更多信息,请参阅此问题

于 2010-04-08T17:20:27.593 回答
3

真正的程序员可以用任何语言编写Fortran Java!Java 要求您(实际上)动态分配所有内容,但 C++ 不需要。

由于没有其他人(至少直接)指出这一点,display因此似乎根本没有理由使用动态分配。只需执行以下操作:

void display(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    Body body;
    body.readSkel("C:\\skel2.skel");
    body.drawBody();

    Body body2;
    body2.readSkel("C:\\skel1.skel");
    body2.drawBody();
    glutSwapBuffers();  
}

如果您readSkel清除了现有的骨架数据,则不需要定义body2,但在不知道的情况下,这是保证事情安全的简单方法。

同样,在您对 Body 的定义中,您似乎也没有做任何需要动态分配的事情。

class Body { 
    std::string skelFile;
    std::string skinFile;
    int totalJoints;
    Skin skin;
    Joint joints[25];
public:
    Body() : totalJoints(0) {}
};

或者更好:

class Body { 
    std::string skelFile;
    std::string skinFile;
    Skin skin;
    std::vector<Joint> joints;
public:
   // presumably other stuff goes here...but you don't need a ctor or dtor.
};

这消除了泄漏任何东西的大多数机会(至少在代码的这些部分中——因为我们还没有看到你的 Skin 或 Joint 类,所以很难猜测它们可能在做什么......

于 2010-04-08T19:42:41.937 回答
1

如果您粘贴一些代码会有所帮助,但我会:

仔细检查您的语法: int *foo = new int[size]; 删除[] foo;

确保所有父级使用动态内存的子类也包含析构函数,即使析构函数是空语句。

于 2010-04-08T17:11:14.343 回答
0

Jochen Kalmbach是您的朋友。

于 2010-04-08T17:35:56.790 回答