我正在使用Visual Studio 2008,开发一个OpenGL窗口。我已经创建了几个用于创建骨架的类,一个用于关节,一个用于皮肤,一个用于Body(用于多个关节和皮肤),另一个用于读取一个skel / skin文件。
在我的每个类中,我正在使用大多数数据的指针,其中大多数是使用= new int [XX]声明的。我有一个删除指针的类的析构函数,使用delete [XX]。
在我的GLUT显示功能中,我让它声明一个正文,打开文件并绘制它们,然后删除显示结尾处的正文。但是程序中某处仍然存在内存泄漏。随着时间的推移,它的内存使用量会以一致的速度不断增加,我将其解释为不被删除的内容。
我不确定过量显示功能是否只是删除Body类或其他内容。我已经按照Visual Studio 2008中的内存泄漏检测步骤进行了操作,它没有报告任何泄漏,但我不能100%确定它是否适合我。我不会精通C ++,所以我可能会忽略一些东西,有人能看到它吗?
来自main:
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;
}
答案 0 :(得分:6)
在此代码中:
Body *body = new Body();
body->readSkel("C:\\skel2.skel");
body->drawBody();
body = new Body();
您正在泄漏Body
,因为您没有删除第一个。
而且:
body->~Body();
delete body;
很奇怪。你没有明确地调用这样的析构函数 - delete
负责调用析构函数。
此代码:
delete[25] joints;
也很奇怪。正确的形式是:
delete [] joints;
您使用的是非标准语法,25
将被忽略。有关详细信息,请参阅this question。
答案 1 :(得分: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.
};
这消除了泄漏任何东西的大部分机会(至少在代码的这些部分 - 因为我们还没有看到你的皮肤或关节类,很难猜出他们可能在做什么......
答案 2 :(得分:1)
如果您粘贴一些代码会有所帮助,但我会:
仔细检查你的语法:int * foo = new int [size];删除[] foo;
确保所有父类使用动态内存的子类也包含析构函数,即使析构函数是空语句。
答案 3 :(得分:0)
Jochen Kalmbach是你的朋友。