Утечка памяти в C ++, не могу найти где - PullRequest
0 голосов
/ 08 апреля 2010

Я использую Visual Studio 2008, Разрабатываю окно OpenGL. Я создал несколько классов для создания скелета, один для суставов, один для кожи, один для тела (который является держателем для нескольких суставов и кожи) и один для чтения файла skel / skin.

В каждом из моих классов я использую указатели для большинства моих данных, большинство из которых объявлено с использованием = new int [XX]. У меня есть деструктор для каждого класса, который удаляет указатели, используя delete [XX].

В моей функции отображения 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 ]

5 голосов
/ 08 апреля 2010

В этом коде:

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 будет игнорироваться. См. этот вопрос для получения дополнительной информации.

3 голосов
/ 08 апреля 2010

Настоящие программисты могут писать 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, трудно догадаться, что они могут делать ...

1 голос
/ 08 апреля 2010

Было бы полезно, если бы вы вставили небольшой код, но я бы:

Дважды проверьте ваш синтаксис: int * foo = new int [size]; удалить [] foo;

Убедитесь, что все дочерние классы, чьи родители используют динамическую память, также содержат деструкторы, даже если деструктор является пустым оператором.

0 голосов
/ 08 апреля 2010
...