2013-07-29 2 views
2

У меня есть следующий класс:утечка ресурсов из массива

class estimate 
{ 
    public: 
     estimate(); 
     ~estimate(); 
     double *tHanning; 
} 

estimate::estimate() 
{ 
    tHanning = NULL; 
    tHanning = new double [1000]; 

    for (int m=0; m<1000; m++) 
    { 
     tHanning[m]=(0.5-0.5*cos(2.0*PI*(m+1)/(1001))); 
    } 
} 

estimate::~estimate() 
{ 
    delete [] tHanning; 
    tHanning = NULL; 
} 

Я не знаю, почему C++ памяти Validator показывает утечку ресурсов в конструкторе, когда я задаю «новый» переменной.

Может кто-нибудь, пожалуйста, помогите мне?

Edit: Как засудить выше класс:

class HBMain 
{ 
    public: 
     HBMain(); 
     ~HBMain(); 
     bool Init(); 
     estimate *objEstimate; 
} 

HBMain :: HBMain() 
{ 
    objEstimate = NULL; 
} 

HBMain :: ~HBMain() 
{ 
    delete objEstimate; 
    objEstimate = NULL; 
} 

bool HBMain :: Init() 
{ 
    .... 
    objEstimate = new estimate(); 
    .... 
} 
+4

Пожалуйста отправьте точное сообщение об ошибке. Кроме того, как вы создаете экземпляры «оценки»? – arne

+5

Как вы используете класс 'оценка'? Вы можете прочитать о [правиле трех] (http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29). –

+0

Спасибо всем. Я отредактировал и поместил код, как я использую класс оценки. –

ответ

1

В качестве альтернативного решения, то почему бы не просто изменить указатель на вектор двойной?

Вы избежите головных болей по поводу утечек памяти.

Редактировать: Для класса HBMain вы также можете изменить свой голый указатель с помощью интеллектуального указателя (shared_ptr) из C++ 11 или библиотеки Boost и удалить деструктор. И вам не придется выполнять весь шаблонный код.

Но вам действительно нужно динамическое распределение для свойства HBMain?

+0

Большое спасибо. Если я использую vector :: double, не будет ли больше памяти? –

+0

Да немного больше, и это будет немного медленнее. Но вы должны иметь в виду, что C++ действительно быстр, поэтому для подавляющего большинства кода это не имеет большого значения. Преимущество: отсутствие головной боли утечки памяти, и это огромный плюс. И это то же самое из умных указателей. – Rak

+0

Еще раз спасибо. Позвольте мне преобразовать все указатели в вектор и посмотреть, сколько памяти требуется. Приветствия. –

1

И ваш конструктор и деструктор классакажутся прекрасными (вы динамически выделяете память с помощью new[] в конструкторе, а delete[] - в деструкторе).

Но я думаю, что у вас могут быть проблемы во время копий.

В самом деле, ваш класс имеет по умолчанию конструктора копирования и operator=, но поведение по умолчанию не хорошо в этом случае; на самом деле, поведение по умолчанию - это просто копия по-членски, но копирование необработанного указателя tHanning - элемент данных - «непроницаемость».

Либо отключить конструктор копирования и operator= (например, объявив их private в C++ 98/03, или с использованием нового синтаксиса = delete C++ 11), или дать надлежащее выполнение для них.

Правильная реализация должна сделать deep копия принадлежащего массиву (с правильным удалением любого ранее выделенного массива).

Я думаю, что самое лучшее, что вы можете сделать, это использовать std::vector<double> вместо необработанного указателя.

Если вы действительно такие весьма ограничены на (относительно небольшой) погона std::vector, а затем рассмотреть вопрос об использовании смарт указатель как std::unique_ptr:

#include <memory> // for std::unique_ptr 

class estimate 
{ 
private: 
    std::unique_ptr<double[]> tHanning; // <--- SMART pointer 

public: 
    estimate() 
     : tHanning(new double[1000]) 
    { 
     for (int m = 0; m < 1000; m++) 
     { 
      tHanning[m] = (0.5-0.5*cos(2.0*PI*(m+1)/(1001))); 
     } 
    } 

    // No need to define destructor - smart pointer automatically deletes its owned stuff 
}; 

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


как чтение Bouns, рассмотрим Rule of Three в C++.


Опять же, в вашем HBMain классе, не использовать необработанный элемент данных estimate *objEstimate указатель. Вместо этого используйте умные указатели как:

class HBMain 
{ 
    .... 
private: 
    std::unique_ptr<estimate> objEstimate; 

    // Again, no need to define a custom destructor for deleting objEstimate. 
    // std::unique_ptr will do proper deletion *automatically*. 
}; 
+0

Большое спасибо за ответ. Использование номера 1000 было только для примера. Как изменить код в конструкторе, где я получаю размер от другого вычисления? Еще раз спасибо. –

+0

Добро пожаловать. Для вашего нового вопроса: вы можете использовать ** метод 'unique_ptr :: reset()' **, что-то вроде этого: 'const int count = GetProperSize(); tHanning.reset (новый double [count]); '. –

+0

Еще раз спасибо за ответ. Так что я должен делать то же, что и выше, если вы хотите изменить размер где-либо еще в коде? –

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