0 / 0 / 0
Регистрация: 26.03.2011
Сообщений: 12
|
||||||
1 | ||||||
Операторы динамического выделения памяти - new/delete26.03.2011, 13:02. Показов 7594. Ответов 38
Метки нет (Все метки)
Здравствуйте.
Я немного не понимаю некоторый момент, связанный с динамическим выделением памяти, а именно - с объемом выделяемой памяти. Дано Разные персональные компьютеры: 1. Win XP Pro SP3 32bit - 2 Gb RAM; 2. Win XP Pro SP3 32bit - 3 Gb RAM; 3. Win Server 2003 64 bit - 8 Gb RAM. Задача Динамически выделить крупный "кусок" RAM (1 Gb и более), а именно - создать массив типа структура. Мое решение
Ни на одном из трех указанных выше ПК - не получается выделить объем памяти более 512 МБайт. В момент попытки динамического выделения памяти - ОС и все запущенное ПО потребляет не более 700 МБайт. То есть всегда свободно достаточное количество памяти, чтобы можно было ею воспользоваться. (В приведенном примере производится попытка выделения памяти объемом больше 512 МБайт). Вопрос 1. Возможно ли вообще выделать больше 512 Мбайт памяти динамически или нет? 2. Можно ли заставить программу "кушать" всю свободную оперативную память и соответственно манипулировать всей свободной оперативной памятью в системе? (К примеру 8 Gb RAM). 3. На сколько я знаю, в С++ рациональнее пользоваться операторами new/delete, вместо функций malloc()/free(). Это правда? Пост Скриптум Не спрашивайте зачем так много программе нужно оперативки. Просто нужно Всем заранее спасибо за Ваши ответы и подсказки. С уважением.
0
|
26.03.2011, 13:02 | |
Ответы с готовыми решениями:
38
По поводу динамического выделения памяти Применение Динамического выделения памяти Функциии динамического выделения и освобождения памяти Как написать программу для динамического выделения памяти с использованием new |
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
|
|
26.03.2011, 17:26 | 22 |
Evg, Что ты подразумеваешь под встроенной конструкцией языка?
0
|
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|
26.03.2011, 17:34 | 23 |
0
|
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
|
|
26.03.2011, 17:36 | 24 |
alex_x_x, вот и я об этом же подумал.
Evg, на вопрос про вектор сможешь ответить?
0
|
26.03.2011, 17:39 | 25 |
А к чему ты спросил про вектор, когда речь шла об отсутствии встроенной конструкции, являющейся аналогом аналога?
Да куда уж мне. Это ведь твой интеллектуальный вклад в данную тему кто-то оценил, а не мой
1
|
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
|
|
26.03.2011, 18:13 | 26 |
я спросил о возможности использования метода ресайз у вектора как алтернативу реалока. Слова "встроенная конструкция" я не заметил.
интересная речевая конструкция, ниразу такую не встречал К сожалению этот кто-то передумал и вернул все как было. А если серьезно, ты можешь ответить нормально, без увертываний?
0
|
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
|
|
26.03.2011, 18:40 | 28 |
0
|
26.03.2011, 18:54 | 29 |
То, что возвращает malloc/realloc - это сплошной участок памяти. Эту память действительно можно использовать произвольным образом. То, что работает через контейнер vector - оно только внешне выглядит как сплошной участок. На самом деле это фрагментированные куски памяти, а оператор [] возвращает указатель на нужную запись путём вычисления, в котором из фрагментов находится участок. То, что тебе выдало malloc, грубо говоря, можно копировать через memcpy, а с вектором - нельзя. Обращение к элементу памяти от malloc'а по индексу делается за константное количество операций (адрес + индекс помноженный на sizeof), а обращение к элементу в vector'е - это вычисления. vector - это, грубо говоря, то, о чём написано в конце поста #5
0
|
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
|
|
26.03.2011, 19:05 | 30 |
Evg
Я надеюсь ты не шутишь. Если нет, то ты чертовски заблуждаешься. В векторе все элементы хранятся сподряд. Можно без проблем взять указатель на нулевой элемент и обращаться к другим элементам, прибавляя оффсет.
1
|
26.03.2011, 19:23 | 31 |
Действиетльно, что-то меня проглючило
Добавлено через 12 минут Действительно, разницы особенно нет. Для vector<char> resize работает раза в два медленнее, чем calloc такого же размера, но это мелочи. С виду вектор действительно является аналогом realloc'а (пусть и не являясь при этом встроенной конструкцией языка)
1
|
20 / 20 / 2
Регистрация: 23.09.2010
Сообщений: 193
|
|
26.03.2011, 20:04 | 32 |
можно узнать почему malloc встроенная конструкция языка ?
malloc так же как и vector вроде является стандартной библиотекой. malloc (#include <stdlib.h>) vector (#include <vector>)
0
|
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
|
|
27.03.2011, 04:10 | 34 |
Вектор для своих целей выделяет память размером заведомо большим, чем необходимо, для того, чтобы при каждом расширении вектора не производить перераспределение памяти. Но когда эта память закончится, вектор будет вынужден выделить память под массив большего размера, скопировать туда элементы старого массива и удалить старый массив. Про вектор: http://cplusplus.com/reference/stl/vector/, и конкретно:
1
|
0 / 0 / 0
Регистрация: 26.03.2011
Сообщений: 12
|
|
27.03.2011, 11:18 [ТС] | 35 |
Вот это Вы тему развили
Evg, мне привел пример того, как можно выделить большущий кусок RAM - "дробить" и блоками выделять. Использую я именно операторы new/delete - мне так удобнее и проще. То есть вопрос полностью решен Так же подчеркнул для себя ряд интересных нюансов в последующих сообщениях. Всем большое спасибо
0
|
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|
27.03.2011, 12:07 | 36 |
кхм, а realloc делает пространственно-временные разрывы? просто делает он тоже самое
1
|
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
|
|
27.03.2011, 12:15 | 38 |
fasked, нет, я про то, что когда не хватает памяти на изменение размера блока - копирует его в другую часть кучи и возвращает новый указатель
про больший резервируемый размер - это вопрос оптимизации
0
|
27.03.2011, 12:46 | 39 |
Сообщение было отмечено как решение
Решение
realloc поступает так же. Если есть возможность добавить память в хвост, то он просто добавляет память (т.е. довыделяет только остаток), если возможности нет, то выделяет новую память полного размера и копирует в него данные из старого участка, после чего старый участок удаляется.
У всех контейнеров (а точнее, у всех шаблонов) есть параметр Allocator, который фактически является менеджером памяти. Этот менеджер памяти на низком уровне так или иначе работает с malloc/realloc. И вполне логично, что менеджер памяти должен всегда отъедать побольше памяти за раз, чтобы поменьше обращаться к malloc/realloc. Да, по скорости это будет медленнее, чем работать напрямую с realloc'ом. Я сравнивал время работы calloc и вектора. Использовал именно calloc, потому что вектор не просто выделает память, но ещё и вызывает дефолтный конструктор для каждого элемента, что в случае с базовыми типами языка означает обнуление (т.е. calloc, а не malloc). Обнуление памяти в calloc'е скорее всего реализовано на ассемблере. Обнуление памяти в векторе - это цикл по всем элементам с записью нуля в каждый элемент (и как бы написан на языке Си++). И компилятор скорее всего сгенерил код, менее эффективный, чем внутри calloc'а Вектор условно можно считать механизмом, которым можно пользоваться взамен malloc/realloc/free. Но это всё-таки объект языка, а потому для работы на низком уровне он менее удобен. Т.е. в случае malloc'а выделил указатель, записал куда-то и работай с ним, а в случае с вектором надо постоянно с собой таскать объект-вектор. Всё это решаемо, но может оказаться менее удобным, чем работа с указателем. Дополнительно при увеличении размера идёт зачастую ненужная работа по обнулению. Но в целом, с виду, можно заменять. На коротком примере проверил максимально разрешённый размер для vector.resize - он совпал с ограничением по realloc'у Спор, направленный в правильное русло, почти всегда заканчивается кучей полезной информации для прочих читателей Любой менеджер памяти всегда выделяет заведомо больше памяти. Т.е. если ты будешь 100 раз довыделять по 1 байту, то обращаться 100 раз к Api системы получается слишком дорого. Куда дешевле выходит при первом обращении, например, выделить сразу 4 килобайта памяти, а при последующих 99 довыделениях просто поправить значение текущего размера массива. тот Allocator, который находится в параметре шаблона, можно переопределить на свой и реализовать свою собственную логику выделения памяти. malloc внутри себя тоже выделяет сразу большой кусок памяти. Это низкоуровневая функция, а потому она умеет работать по конкретным значениям виртуальных адресов и выделяет память с точностью до границы страницы. Ибо аппаратный контроль за допустимой областью памяти делается именно с точностью до страницы
3
|
27.03.2011, 12:46 | |
27.03.2011, 12:46 | |
Помогаю со студенческими работами здесь
39
Как удалить элемент из массива и сжать его (без динамического выделения памяти)? Сумма элементов первой и последней строчки матрицы с использованием динамического выделения памяти Реализовать «массив целых чисел». Обработать ошибки динамического выделения памяти. Переопределить опе Функция динамического выделения памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |