изучаю STL, вопросы по распределению памяти
От: zdx  
Дата: 14.02.05 11:45
Оценка:
Начал изучать STL.

Лазил тут по форуму и появился вопрос для модераторов:
А не сделать ли отдельную ветку форума "STL/BOOST", есть же например ATL/WTL.
Ну это так, к слову (наверное я уже 151-ый такой умный по этому поводу)

Собственно вопрос следующий.

допустим есть:

struct stlstruct
{
    CString str1;
    int     num;
    char   rrr[1000000];

};


Я создаю :


vector< stlstruct > vStlStr;
..............

void CSTL1Dlg::AddElem() 
{
   stlstruct addtemp;
    
    addtemp.str1 = "string1";
    addtemp.num = 1;
    
    vStlStr.push_back (addtemp);
}

...............

void CSTL1Dlg::OnClear() 
{
    vStlStr.clear ();
}


Все работает нормально. Но в структуре есть член rrr[1000000]
Так вот при каждом добавлении в вектор "push_back (addtemp)" в диспетчере задач видно, память, которую жрет прога
увеличивается грубо на 1 кб.

А если сделать vStlStr.clear ();, то в диспетчере видно, что память, занимаемая прогой не освобождается.
Что делать: — 1) я чего то упустил в данном примере
2) начать изучать аллокаторы (хотя я пока смутно представляю, зачем они нужны)
3) говорить что кривой диспетчер

спасибо.
Re: изучаю STL, вопросы по распределению памяти
От: CrystaX Россия https://crystax.me/
Дата: 14.02.05 11:52
Оценка:
Здравствуйте, zdx, Вы писали:

zdx>Что делать: — 1) я чего то упустил в данном примере

zdx> 2) начать изучать аллокаторы (хотя я пока смутно представляю, зачем они нужны)
zdx> 3) говорить что кривой диспетчер

Operating System Memory Manager != CRT Memory Manager
Используй для этих целей другие тулзы. BoundsChecker, например.

zdx>спасибо.


Пожалуйста.
... << RSDN@Home 1.1.4 >>
Re: изучаю STL, вопросы по распределению памяти
От: tarkil Россия http://5209.copi.ru/
Дата: 14.02.05 11:54
Оценка:
Здравствуйте, zdx, Вы писали:

zdx>А если сделать vStlStr.clear ();, то в диспетчере видно, что память, занимаемая прогой не освобождается.


Фишка в поведении vector — он выделяет память под элементы, но без явного указания её не освобождает. Если вставишь другие элементы — он старую память заюзает. Освобождать так:

vector< stlstruct >().swap( vStlStr );
vStlStr.reserve( 0 ); // альтернативный вариант, но он не обязательно сработает, STL этого не обещает :-)
--
wbr, Peter Taran
Re[2]: изучаю STL, вопросы по распределению памяти
От: zdx  
Дата: 14.02.05 12:29
Оценка:
T>
T>vector< stlstruct >().swap( vStlStr );
T>vStlStr.reserve( 0 ); // альтернативный вариант, но он не обязательно сработает, STL этого не обещает :-)
T>


да, вроде работает. И даже диспетчер показывает, что память освобождается.

Но тогда вопрос, если контейнер не указателей на объекты, а контейнер объектов просто (то есть то, что я привел в примере) освобождать clear() или erase(iter) по одиночке. ЭТО ПРАВИЛЬНО ????? несмотря на диспетчер?
(просто не хочется видеть, чтобы по прошествию долгого времени работы проги, память под нее разраслась бы)

или надо както более "правильнее" освобождать контейнер?
Re: изучаю STL, вопросы по распределению памяти
От: ilejn Россия  
Дата: 14.02.05 12:34
Оценка:
Здравствуйте, zdx

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

С точки зрения OS уменьшения [скорее всего] не будет.
Re[2]: изучаю STL, вопросы по распределению памяти
От: zdx  
Дата: 14.02.05 12:37
Оценка:
Здравствуйте, ilejn, Вы писали:

I>Здравствуйте, zdx


I>Попробуй безо всякого STL понаблюдать

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

I>С точки зрения OS уменьшения [скорее всего] не будет.



а как можно будет так создавать структуры? полагаю через new . Но в данном случае
это не совсем то. (контейнер указателей я уже умею удалять)
Re[3]: изучаю STL, вопросы по распределению памяти
От: tarkil Россия http://5209.copi.ru/
Дата: 14.02.05 12:51
Оценка:
Здравствуйте, zdx, Вы писали:

zdx>Но тогда вопрос, если контейнер не указателей на объекты, а контейнер объектов просто (то есть то, что я привел в примере) освобождать clear() или erase(iter) по одиночке. ЭТО ПРАВИЛЬНО ?????


Смотря что Вы хотите. Метод clear выполняет логическое удаление эмитентов. Массив (vector) после этого становится пустой, empty() вернёт истину. Но память он придерживает за собой, типа запас карман не тянет Для гарантированного освобождения памяти нужно вызывать swap с пустым вектором.

Собственно, у меня ни разу ещё не было необходимости делать так, если экземпляр вектора больше не будет наполняться, то зачем ему жить?

Поэлементный erase совершенно избыточный и вредный — он же копирует "хвост" за удаляемым элементом на новые позиции (разве что удалять с конца... но clear то же в точности делает). Если Вы беспокоитесь о деструкторах элементов, то они вызываются, каким бы способом элементы не уничтожались: clear, erase, в деструкторе...

zdx>(просто не хочется видеть, чтобы по прошествию долгого времени работы проги, память под нее разраслась бы)


Убивайте ненужные контейнеры. Помните, что глобальные переменные — зло. Используйте list для больших объектов (он под каждый элемент выделяет свой блок памяти и сразу освобождает при удалении). Обычно этого достаточно.
--
wbr, Peter Taran
Re: изучаю STL, вопросы по распределению памяти
От: _Winnie Россия C++.freerun
Дата: 15.02.05 07:47
Оценка:
Здравствуйте, zdx, Вы писали:

zdx>А если сделать vStlStr.clear ();, то в диспетчере видно, что память, занимаемая прогой не освобождается.


реализации STL от SGI и STLport никогда не возвращают память.
метод clear не возвращает память во всех реализациях STL
Правильно работающая программа — просто частный случай Undefined Behavior
Re: изучаю STL, вопросы по распределению памяти
От: staseaux  
Дата: 15.02.05 22:19
Оценка:
Здравствуйте, zdx, Вы писали:

zdx>А если сделать vStlStr.clear ();, то в диспетчере видно, что память, занимаемая прогой не освобождается.

zdx>Что делать: — 1) я чего то упустил в данном примере
zdx> 2) начать изучать аллокаторы (хотя я пока смутно представляю, зачем они нужны)
zdx> 3) говорить что кривой диспетчер

zdx>спасибо.


Аллокаторы тут не причем. Просто вектор никогда не сжимается. То есть при изменении размера вектора в меньшую сторону освобожденная память не возвращается вектором аллокатору (который уже может вернуть память системе). Это сделано, чтобы обеспечить высокую производительность.
Впрочем есть трик, который описан, например, у Саттера:

std::vector<char> big_vector(1000000);
std::vector<char>().swap(big_vector);


Вторая строка делает то, что ты хочешь
... << RSDN@Home 1.1.3 stable >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.