Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Освобождение памяти из-под массива


Автор: alexr3 2.4.2010, 12:39
Добрый день!

Я с C++ знаком не очень близко. В основном с Java, но тут пришлось написать программку на C++ для обработки большого объема данных (сотни Гб). В программе встречается довольно много конструкций вида:

Код

SomeClass ** arr = new SomeClass*[size]; // Конструктора SomeClass() нет!
for (int i=0; i < size; i++){
    arr[i] = new SomeClass(x, y, z);
}

...


delete[] arr;


Вот насколько корректно оператор delete[] освободить память? У меня на тестовых объемах данных все работает хорошо. На реальных (больших) - вылетает с ошибкой о нехватке памяти (работает на юниксовом сервере, 64-bit, 16Гб ОЗУ). Но обработка данных ведется построчно и, грубо говоря, в памяти одновременно должно находиться не так уж много данных. Поэтому мне кажется, что где-то утечка памяти идет и от строки к строке объем свободной памяти все уменьшается.

А еще как отработает такая конструкция:
Код

void *buffer = (void *) new char[size];
delete[] (char*)buffer;

?

Автор: KelTron 2.4.2010, 12:54
Нужно удалить данные из массива, а потом сам массив ссылок, а у тебя происходит только второе, надо так:
Код

for (int i=0; i < size; i++){
    delete arr[i];
}

delete[] arr;

Автор: alexr3 2.4.2010, 12:58
Спасибо за ответ!

Мне почему-то казалось, что оператора 
Код
delete[] 
тем и отличается от 
Код
delete
, что сначала выполнит 
Код
delete 
для каждого своего элемента. Нет?

Автор: toxx 2.4.2010, 13:01
alexr3
еще желательно присвоить указателю 0 
Код

arr=0;


Цитата

delete[] тем и отличается от  delete


Да все верно, только как ты память выделяешь, так ты её и освобождаешь

Автор: KelTron 2.4.2010, 14:20
Цитата(alexr3 @  2.4.2010,  12:58 Найти цитируемый пост)
отличается от 

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

Автор: bsa 2.4.2010, 15:07
alexr3, чтобы такой проблемы не было, нужно использовать std::vector<boost::shared_ptr<SomeClass> >. Вместо boost::shared_ptr можно использовать свой умный указатель с подсчетом ссылок.

Автор: alexr3 2.4.2010, 20:10
Спасибо за ответы. Про boost где-то уже слышал, попробую разобраться.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)