Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 5.00
Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
#1

Освобождение памяти, занятой вектором - C++

07.09.2011, 14:30. Просмотров 3751. Ответов 62
Метки нет (Все метки)

У меня задача требует чтобы у вектора было в резерве не более 100 элементов. При постоянном росте вектора понятно как это обеспечить, а вот как быть при уменьшении количества элементов? Я не в курсе последних стандартов, подскажите есть ли сейчас способы гарантированного освобождения памяти, занятой вектором, и вообще какие способы существуют?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.09.2011, 14:30     Освобождение памяти, занятой вектором
Посмотрите здесь:

Освобождение неиспользуемой вектором памяти - C++
Есть ли вменяемый способ освободить зарезервированную память, которая зарезервирована сверх того, что нужно? Одним словом...

Освобождение памяти в списках - C++
#pragma once class Node { public: int value; Node * next; Node(int data); ~Node(); };

Выделение и освобождение памяти - C++
Доброго времени суток. Пишу класс по ООП, и назрел один вопрос, связанный с моментом выделения и освобождения памяти. class SOK { ...

Массив, освобождение памяти - C++
что я сделал не так? #include "stdafx.h" #include <conio.h> #include <stdio.h> #include <math.h> #include <iostream> ...

Правильное освобождение памяти - C++
Есть код class Test { public: int **container; int counter = 0; Test(unsigned int size) { container = new int*;

Освобождение и выделение памяти - C++
Помогите разобраться с программой, где здесь выделение памяти (как я понял это new) и где освобождение памяти. #include <iostream> ...

Правильное освобождение памяти - C++
Здрасти. Двумерный динам. массив: int** matr=new int*; for (int i=0; i<rows; ++i) matr=new int; ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
08.09.2011, 11:57     Освобождение памяти, занятой вектором #46
-=ЮрА=-, не верите в динамическое выделение памяти, вот другой пример: таблица виртуальных функций. Конструкторы (и только конструкторы) её настраивают, никакими void Init() вы не отделаетесь.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <stdlib.h> // для malloc
 
using namespace std;
 
class CDummy
{
public:
    CDummy(){};
 
    virtual void out() = 0;
};
 
class CStrDummy : public CDummy
{
public:
    CStrDummy() : CDummy(){};
 
    virtual void out(){
        cout << "String\n";
    }
};
 
class CIntDummy : public CDummy
{
public:
    CIntDummy() : CDummy(){};
 
    virtual void out(){
        cout << 256;
    }
};
 
int main()
{
    // так не работает (никто не настроил таблицу виртуальных функций)
    /*
    CStrDummy * strPtr = (CStrDummy*)malloc( sizeof(CStrDummy) );
    CIntDummy * intPtr = (CIntDummy*)malloc( sizeof(CIntDummy) );
    */
 
    // так работает:
    CStrDummy * strPtr = new CStrDummy();
    CIntDummy * intPtr = new CIntDummy();
 
    CDummy * dum = strPtr;
    dum->out();
    dum = intPtr;
    dum->out();
 
    // в случае с malloc до сюда просто не дойдёт
    delete strPtr;
    delete intPtr;
 
    return 0;
}
Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
08.09.2011, 21:18  [ТС]     Освобождение памяти, занятой вектором #47
Deviaphan, нет, другой контейнер не подойдет, т.к. есть одна тонкость, нужна мгновенная сортировка по запросу.

Господа, подведите итоги пжалуста , ушли в личные беседы...
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
08.09.2011, 21:50     Освобождение памяти, занятой вектором #48
Цитата Сообщение от Union Посмотреть сообщение
нужна мгновенная сортировка по запросу.
Может тогда std::multiset использовать? Он всегда отсортирован,
и лишней памяти не запрашивает.
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
08.09.2011, 23:06     Освобождение памяти, занятой вектором #49
Union, вот мои итоги. Насколько могу судить, вектор (по крайней мере у меня) не отдаёт память после resize() в меньшую сторону. Тупо деструкторы вызывает и всё.
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
08.09.2011, 23:30     Освобождение памяти, занятой вектором #50
вектор (по крайней мере у меня) не отдаёт память после resize()
и не должен. Иначе пришлось бы заниматься ненужным копированием.
Освобождение памяти, занятой вектором тут еще это сказал.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 06:41     Освобождение памяти, занятой вектором #51
Цитата Сообщение от Union Посмотреть сообщение
нужна мгновенная сортировка по запросу
Мгновенной сортировки не бывает. Это фантастика.
Есть std::set - это не фантастика.

Тут ещё один момент не учли. Создавая копию вектора меньшего размера создаётся его копия. Т.е. потребление памяти временно удваивается. Использование аллокатора эту проблему не решает, т.к. он выделяет память, а не перераспределяет имеющуюся в векторе (или нужно очень сильно над реализацией попотеть, но по моему для std::vector нельзя написать аллокатор через realloc, чтобы не создавать копию вектора, ведь для этого придётся переписывать логику работы вектора).

Итого: Пиши собственный контейнер используя malloc/realloc/free и размещающий new. Или я недостаточно хорошо знаю std::vector.)
LosAngeles
Заблокирован
09.09.2011, 06:50     Освобождение памяти, занятой вектором #52
раздули на шесть страниц какую то фигню, чем вариант со своп не устраивает ТС, вот даже код привёл Мистер Хэ
Цитата Сообщение от Mr.X Посмотреть сообщение
void do_minimize_capacity(T_container& v)
{
T_container(v).swap(v);
}
Добавлено через 44 секунды
и никаких копий не создаётся
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 06:54     Освобождение памяти, занятой вектором #53
Цитата Сообщение от LosAngeles Посмотреть сообщение
и никаких копий не создаётся
По твоему безымянный объект T_container(v) не копия?
LosAngeles
Заблокирован
09.09.2011, 07:14     Освобождение памяти, занятой вектором #54
да создаётся, я просто не посмотрел что копировал. Но адаптировать данный пример под требования автора

Цитата Сообщение от Union Посмотреть сообщение
подскажите есть ли сейчас способы гарантированного освобождения памяти, занятой вектором
переделать просто:
C++
1
2
3
4
5
template<class T_container>
void clear(T_container& v)
{
    T_container().swap(v);
}
никаких копий не создаётся
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1286 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 07:27     Освобождение памяти, занятой вектором #55
Цитата Сообщение от LosAngeles Посмотреть сообщение
переделать просто:
Это удаляет ВСЕ объекты из контэйнера, а требуется удалить только "лишнюю" зарезервированную память, а не очистить. По крайней мере фразу "уменьшение количества элементов" я не приравниваю к слову "очистить".
Кстати, используя вектор в куче, вместо стэка, проблема с гарантированным освобождением памяти решается пересозданием объекта.)
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.09.2011, 11:54     Освобождение памяти, занятой вектором #56
На счёт другого контейнера: если std::list устроит вас по скорости обхода и количеству избыточной информации на узел (вроде, два указателя и всё, но я могу ошибаться) - то его можно обрезать под нужную длину без пересоздания кучи элементов. и память освобождается (gcc 4.9 mingw)
Union
17 / 17 / 2
Регистрация: 16.08.2010
Сообщений: 252
09.09.2011, 19:43  [ТС]     Освобождение памяти, занятой вектором #57
Про своп я уже написал, когда я изучал эту тему, не нашел нигде инфы по поводу гарантии со стороны стандарта что новый вектор будет меньше старого. А сейчас вот не знаю и спрашиваю...

Тогда ещё такой вопрос, что делает malloc_trim(0) ?
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.09.2011, 20:01     Освобождение памяти, занятой вектором #58
Union, в манах сказано так:

malloc_trim() explicitly requests that any unused memory space be returned to the OS. Note that this happens automatically when free() is called with a sufficiently large chunk; see the M_TRIM_THRESHOLD and M_TOP_PAD parameters, above. pad specifies the number of bytes to be retained for use in future allocation requests; when called by free(), this is the value of M_TOP_PAD.
Добавлено через 3 минуты
malloc_trim() явным образом возвращает любую неиспользованную память системе. Это проиходит автоматически, когда вызывается free() для достаточно большого сегмента кучи. См. параметры M_TRIM_THRESHOLD и M_TOP_PAD выше (здесь ниже). pad определяет количество байт, которые необходимо оставить для запросов на выделение памяти в будущем. Когда вызывается из free(), это значение равно M_TOP_PAD.

Добавлено через 5 минут
M_TRIM_THRESHOLD
Unused memory is returned to the OS when the size available to be returned exceeds the given value.

Note that not all unused memory is able to be returned to the OS; in particular, it is not possible to return an unused block when an in-use block lies between it and the ``top'' of the data segment. However, the free block may be used to satisfy future allocation requests.

Smaller values for this parameter cause sbrk() to be called more frequently with a negative argument, reducing memory usage, but with increased overhead of extra syscalls. A value of -1 disables trimming. Default: 128*1024.
M_TRIM_THRESHOLD
Неиспользованная память возвращается системе, когда размер памяти, доступной для возврата, превышает данное значение.

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

Меньшие значения для этого параметра приводят к тому, что sbrk() вызывается чаще с отрицательным аргументом, уменьшая использование памяти, но увеличивая накладные расходы на дополнительные системные вызовы. Значение -1 запрещает (отсечение? возврат памяти ОС?). Значение по-умолчанию: 128*1024.

Добавлено через 4 минуты
M_TOP_PAD
When sbrk() is called with a positive argument to allocate additional address space, the given value specifies an additional amount to be allocated, beyond what is necessary to satisfy the request. This value also defines an amount of address space which is not released to the OS when sbrk() is called with a negative argument. Again, the intent is to minimize the number of syscalls, without needlessly using large usage of memory. Default: 0 (allocation requests are internally rounded up to the page size, and the extra allocated size is already sufficient to reduce the syscall overhead).
M_TOP_PAD
Когда для выделения дополнительного адресного пространства вызывается sbrk() с положительным аргументом, данное значение определят количество памяти, выделяемой сверх необходимого. Это значение также определяет количество адресного пространства, которое не отдаётся системе когда вызывается sbrk() с отрицательным аргументом. Смысл этого - в уменьшении количества системных вызовов без увеличения нецелесообразного расхода памяти. Значение по-умолчанию: 0 (запросы на выделение памяти округляются в большую сторону до размера страницы, и памяти, выделенной дополнительно, достаточно для уменьшения расходов на системные вызовы.

Добавлено через 1 минуту
Короче, вот эта страница в сети.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
09.09.2011, 20:27     Освобождение памяти, занятой вектором #59
Цитата Сообщение от Union Посмотреть сообщение
Про своп я уже написал, когда я изучал эту тему, не нашел нигде инфы по поводу гарантии со стороны стандарта что новый вектор будет меньше старого. А сейчас вот не знаю и спрашиваю...
В стандарте написано только:
«The constructor template <class InputIterator> vector(class InputIterator first, class InputIterator last) makes only N calls to the copy constructor of T (where N is the distance between first and last) and no reallocations if iterators first and last are of forward, bidirectional, or random access categories. It makes order N calls to the copy constructor of T and order logN reallocations if they are just input iterators.»
С другой стороны, этот «трюк» со свопом приводят в своих книгах такие столпы C++ как Степанов (создатель STL), Остерн (один из разработчиков SGI STL), а также всем ведомый Александреску.
А чем вас std::multiset не устраивает?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.11.2013, 14:29     Освобождение памяти, занятой вектором
Еще ссылки по теме:

Выделение и освобождение памяти в c++ - C++
Не давно наткнулся на такую замечательность : system(&quot;PAUSE&quot;);//1 раз int *p = new int; // память system(&quot;PAUSE&quot;);//2 раз ...

Освобождение памяти и фишки VS - C++
1) Откуда delete знает, сколько элементов в массиве, ведь обычный sizeof(a), где a - (допустим) int* - ничего не даст? Если &quot;он&quot; это знает,...

Освобождение памяти со структурой - C++
Всем привет. Есть структура: struct ClientInfo { const char* szUid; const char* szName; const char* szSurname;

Освобождение динамической памяти - C++
После первого вызова функции(при повторном) пишет ошибку. В функции sort один из элементов массива становится недоступным для чтения. Если...

Стек и освобождение памяти - C++
Пишу класс стека, реслизую в виде односвязного списка. stack.h #ifndef STACK_H_INCLUDED #define STACK_H_INCLUDED template &lt;class...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
SatanaXIII
Супер-модератор
Эксперт С++
5603 / 2637 / 242
Регистрация: 01.11.2011
Сообщений: 6,497
Завершенные тесты: 1
12.11.2013, 14:29     Освобождение памяти, занятой вектором #60
Нда. Короче поговорили про память, но не поговорили про вектор.
Почему не срабатывает трюк непосредственно с самим вектором?
C++
1
v.swap(v);
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream.h>
#include <vector.h>
 
int main()
{
vector<int> v;
  v.reserve(100000);
 v.push_back(1);
 v.push_back(2);
 v.push_back(3);
cout << "size=" << v.size() << endl;
cout << "capacity=" << v.capacity() << endl;
 
v.erase(v.begin(), v.end()); ////
v.clear();                     //
v.resize(0);                   //
v.reserve(1);                ////
 
v.swap(v);
 
cout << "size=" << v.size() << endl;
cout << "capacity=" << v.capacity() << endl;
 
 
cin.ignore();
return 0;
}
Код
size=3
capacity=100000
size=0
capacity=100000
Yandex
Объявления
12.11.2013, 14:29     Освобождение памяти, занятой вектором
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru