2013-06-13 6 views
1

, так что .. я изо всех сил пытался освободить массив.
У меня нет ни малейшего понятия о том, почему есть память, но почему-то есть одна.
Я не выделял никакой памяти нигде кроме основной функции.Освободить массив указателей - C++

#include <iostream> 
#include "Motorboat.h" 
#include "Sailboat.h" 

using namespace std; 
void printSailBoats(Boat* arr[], int nrOfElements); 
int main() { 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // used to check for memoryleaks in debug mode 

    Boat* test[4]; 
    int nrOfElements = 4; 

    test[0] = new Motorboat("heeelllooo",15000,"v100"); 
    test[1] = new Sailboat("saaailboat",1004,43.5); 
    test[2] = new Motorboat("ASDK",4932,"Blabla"); 
    test[3] = new Sailboat("DKEOK",4992,103.4); 

    printSailBoats(test,nrOfElements); 

    for(int i=0; i<4; i++) { 
     delete test[i]; 
    } 

    return 0; 
} 

void printSailBoats(Boat* arr[], int nrOfElements) { 
     // prints all sailboats 
} 

EDIT: добавлены классы. Boat.h:

#ifndef BOAT_H 
#define BOAT_H 
#include <string> 
using namespace std; 

class Boat { 
    public: 
     virtual void setModel(string newModel) = 0; 
     virtual void setPrice(int newPrice) = 0; 
     virtual string getModel() const = 0; 
     virtual int getPrice() const = 0; 
     virtual string getType() const = 0; 
     virtual string toString() const = 0; 
}; 
#endif 

Sailboat.h:

#ifndef SAILBOAT_H 
#define SAILBOAT_H 
#include "Boat.h" 

class Sailboat: public Boat { 
    private: 
     double sailArea; 
     string model; 
     int price; 

    public: 
     Sailboat(string model, int price, double sailArea); 
     void setSailArea(double newSailArea); 
     double getSailArea() const; 
     string toString() const; 
     void setModel(string newModel); 
     void setPrice(int newPrice); 
     string getModel() const; 
     int getPrice() const; 
     string getType() const; 
}; 
#endif 

Sailboat.cpp:

#include "Sailboat.h" 

Sailboat::Sailboat(string model, int price, double sailArea) { 
    this->model = model; 
    this->price = price; 
    this->sailArea = sailArea; 
} 

// Setters, getters and toString... 

Это в значительной степени то же самое для класса моторной лодки, за исключением, что есть string, чтобы сохранить имя движка вместо sailarea.

+0

Что такое определение '' классов Boat' и Motorboat'? – Inspired

+8

Действительно ли ваш драбтер шлюпки виртуальный? –

+1

Есть ли распределения внутри моторной лодки() Парусник() и Лодка()? – Yamodax

ответ

1

Добавление этого после просмотра определения:

class Boat { 
    public: 
     Boat() 
      { } 
     virtual ~Boat() // <--- this is the real catch! 
        { } 

     ... 
}; 
+0

Спасибо, отлично работает! –

1

Возможно, это утечка внутри ваших конструкторов. Мое предложение состоит в том, чтобы создать деструкторы для каждого из классов, которые вы определяете, чтобы удалить любые объекты, созданные в конструкторе.

1

Что вы можете сделать, это добавить

#define _CRTDBG_MAP_ALLOC 
#include <Crtdbg.h> 

С утечки памяти выход, он должен дать вам файл и строка, где оставшиеся блок был выделен.

Также разместите printf("Destructor of xxxx\n"); и т. Д. В каждом из деструкторов (лодка, парусник, мотобайт). Они должны быть вызваны/напечатаны при удалении.

Но они будут вызываться только в том случае, если деструктор базовых вызовов (Баот) отмечен как виртуальный. В противном случае вы получите только ЛАДЬЯ-деструкторов называются (и, вероятно, теряет память, которая была выделена в Парусник и Моторная лодка)

+0

Спасибо! я обязательно буду учитывать это в следующий раз, когда я попытаюсь найти memoryleaks! :) –

+0

ОК :-). Кроме того, ознакомьтесь с виртуальным деструктором. Ответ, который вы отметили правильно, является лишь обходным путем. Истинная проблема в том, что вам нужен виртуальный деструктор для Boat. – Yamodax

2

утечка здесь:

for(int i=0; i<4; i++) { 
     delete test[i]; 
    } 

Он удаляет элементы, как если бы они были тот же тип, что и базовый класс. И.Е. если у вас есть какая-либо дополнительная информация в производном классе, она будет протекать.

Например:

delete (Sailboat*)test[i] 

отличается

delete (Boat*)test[i] 

Вы должны бросить тест [я] к соответствующему типу перед его удалением. Восстановить тип, который вы создали, может быть трудным, поэтому я бы рекомендовал вам просто использовать интеллектуальные указатели вместо этого, а не беспокоиться об удалении.

Редактировать: Кроме того, виртуальные деструкторы решают эту проблему. Я до сих пор все для умных указателей;)

+3

Вот что такое полиморфизм (не нужно заботиться об этом, потому что оба происходят от Лодки). Добавление «виртуального» в деструктор - это уловка в основном. – Yamodax

+0

@ Симодакс: Ты прав. – AndyG

+0

Спасибо большое! утечка исчезла. я обязательно проверю умные указатели. –

Смежные вопросы