Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/41: Рейтинг темы: голосов - 41, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 26.03.2011
Сообщений: 12
1

Операторы динамического выделения памяти - new/delete

26.03.2011, 13:02. Показов 7614. Ответов 38
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.

Я немного не понимаю некоторый момент, связанный с динамическим выделением памяти, а именно - с объемом выделяемой памяти.

Дано
Разные персональные компьютеры:
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 и более), а именно - создать массив типа структура.

Мое решение

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
/* Общий размер структуры = 20 Байт */
struct my_struct 
{
  long int f0;
  long int f1;
  long int f2;
  long int f3;
  long int f4;
}
 
my_struct *p_my_array;
 
/* Пытаюсь выделать 20 * 30000000 Байт */
try 
{
  p_my_array = new my_struct[30000000];  
} catch (bad_alloc) { /* Обработка исключения в случае неудачи при выделении памяти */ }
 
/*
...
Ряд действий
...
*/
 
delete [] p_my_array;
Проблема
Ни на одном из трех указанных выше ПК - не получается выделить объем памяти более 512 МБайт.
В момент попытки динамического выделения памяти - ОС и все запущенное ПО потребляет не более 700 МБайт.
То есть всегда свободно достаточное количество памяти, чтобы можно было ею воспользоваться.
(В приведенном примере производится попытка выделения памяти объемом больше 512 МБайт).

Вопрос
1. Возможно ли вообще выделать больше 512 Мбайт памяти динамически или нет?
2. Можно ли заставить программу "кушать" всю свободную оперативную память и соответственно манипулировать всей свободной оперативной памятью в системе? (К примеру 8 Gb RAM).
3. На сколько я знаю, в С++ рациональнее пользоваться операторами new/delete, вместо функций malloc()/free(). Это правда?

Пост Скриптум
Не спрашивайте зачем так много программе нужно оперативки. Просто нужно

Всем заранее спасибо за Ваши ответы и подсказки.
С уважением.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.03.2011, 13:02
Ответы с готовыми решениями:

По поводу динамического выделения памяти
Допустим, в программе вызывается функция SomeFunc(), описанная как void SomeFunc(){ int arr;...

Применение Динамического выделения памяти
Надо решить задачу написав функцию. Нужно выделить память использую malloc. Помогите Плиз..!...

Функциии динамического выделения и освобождения памяти
Необходим написать функции выделения и освобождения памяти под двумерный динамический массив....

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

38
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
26.03.2011, 17:01 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от slice Посмотреть сообщение
Ты случайно не знаешь, как ведет себя вектор при ресайзе?
А что, вектор уже стал встроенной конструкцией C++?
0
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
Цитата Сообщение от Evg Посмотреть сообщение
А что, вектор уже стал встроенной конструкцией C++?
не менее встроенная чем malloc
0
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 17:36 24
alex_x_x, вот и я об этом же подумал.
Evg, на вопрос про вектор сможешь ответить?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
26.03.2011, 17:39 25
Цитата Сообщение от slice Посмотреть сообщение
Evg, Что ты подразумеваешь под встроенной конструкцией языка?
А к чему ты спросил про вектор, когда речь шла об отсутствии встроенной конструкции, являющейся аналогом аналога?

Цитата Сообщение от slice Посмотреть сообщение
Evg, на вопрос про вектор сможешь ответить?
Да куда уж мне. Это ведь твой интеллектуальный вклад в данную тему кто-то оценил, а не мой
1
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 18:13 26
Цитата Сообщение от Evg Посмотреть сообщение
А к чему ты спросил про вектор, когда речь шла об отсутствии встроенной конструкции, являющейся аналогом аналога?
я спросил о возможности использования метода ресайз у вектора как алтернативу реалока. Слова "встроенная конструкция" я не заметил.


Цитата Сообщение от Evg Посмотреть сообщение
аналогом аналога
интересная речевая конструкция, ниразу такую не встречал



Цитата Сообщение от Evg Посмотреть сообщение
Да куда уж мне. Это ведь твой интеллектуальный вклад в данную тему кто-то оценил, а не мой
К сожалению этот кто-то передумал и вернул все как было. А если серьезно, ты можешь ответить нормально, без увертываний?
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
26.03.2011, 18:34 27
Цитата Сообщение от slice Посмотреть сообщение
я спросил о возможности использования метода ресайз у вектора как алтернативу реалока
А ты и в правду считаешь, что это альтернатива реаллоку?

Цитата Сообщение от slice Посмотреть сообщение
А если серьезно, ты можешь ответить нормально, без увертываний?
Могу, но зачем? Мы ж вроде как бессмысленно препираемся
1
79 / 78 / 6
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 18:40 28
Цитата Сообщение от Evg Посмотреть сообщение
А ты и в правду считаешь, что это альтернатива реаллоку?
да


Цитата Сообщение от Evg Посмотреть сообщение
Могу, но зачем? Мы ж вроде как бессмысленно препираемся
препираться мне надоело
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
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
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
26.03.2011, 22:42 33
Цитата Сообщение от Saiberg Посмотреть сообщение
можно узнать почему malloc встроенная конструкция языка ?
А никто и не говорил, что malloc встроенная. new/delete - встроенные
1
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
27.03.2011, 04:10 34
Цитата Сообщение от slice Посмотреть сообщение
Получим ли мы эффект аналогичный реалоку(если есть возможность то блок памяти просто расширяется без копирования на новое место)?
Вектор для своих целей выделяет память размером заведомо большим, чем необходимо, для того, чтобы при каждом расширении вектора не производить перераспределение памяти. Но когда эта память закончится, вектор будет вынужден выделить память под массив большего размера, скопировать туда элементы старого массива и удалить старый массив. Про вектор: http://cplusplus.com/reference/stl/vector/, и конкретно:
Reallocations may be a costly operation in terms of performance, since they generally involve the entire storage space used by the vector to be copied to a new location.
Так что vector::resize все же нельзя считать аналогом realloc'a, если я вообще понял суть обсуждаемого вопроса.
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
Цитата Сообщение от Nameless One Посмотреть сообщение
Так что vector::resize все же нельзя считать аналогом realloc'a, если я вообще понял суть обсуждаемого вопроса.
кхм, а realloc делает пространственно-временные разрывы? просто делает он тоже самое
1
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
27.03.2011, 12:13 37
Цитата Сообщение от alex_x_x Посмотреть сообщение
кхм, а realloc делает пространственно-временные разрывы? просто делает он тоже самое
То есть realloc тоже выделяет заведомо больше памяти?
0
бжни
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
27.03.2011, 12:15 38
fasked, нет, я про то, что когда не хватает памяти на изменение размера блока - копирует его в другую часть кучи и возвращает новый указатель
про больший резервируемый размер - это вопрос оптимизации
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
27.03.2011, 12:46 39
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Nameless One Посмотреть сообщение
Так что vector::resize все же нельзя считать аналогом realloc'a, если я вообще понял суть обсуждаемого вопроса.
realloc поступает так же. Если есть возможность добавить память в хвост, то он просто добавляет память (т.е. довыделяет только остаток), если возможности нет, то выделяет новую память полного размера и копирует в него данные из старого участка, после чего старый участок удаляется.

У всех контейнеров (а точнее, у всех шаблонов) есть параметр Allocator, который фактически является менеджером памяти. Этот менеджер памяти на низком уровне так или иначе работает с malloc/realloc. И вполне логично, что менеджер памяти должен всегда отъедать побольше памяти за раз, чтобы поменьше обращаться к malloc/realloc.

Да, по скорости это будет медленнее, чем работать напрямую с realloc'ом. Я сравнивал время работы calloc и вектора. Использовал именно calloc, потому что вектор не просто выделает память, но ещё и вызывает дефолтный конструктор для каждого элемента, что в случае с базовыми типами языка означает обнуление (т.е. calloc, а не malloc). Обнуление памяти в calloc'е скорее всего реализовано на ассемблере. Обнуление памяти в векторе - это цикл по всем элементам с записью нуля в каждый элемент (и как бы написан на языке Си++). И компилятор скорее всего сгенерил код, менее эффективный, чем внутри calloc'а

Вектор условно можно считать механизмом, которым можно пользоваться взамен malloc/realloc/free. Но это всё-таки объект языка, а потому для работы на низком уровне он менее удобен. Т.е. в случае malloc'а выделил указатель, записал куда-то и работай с ним, а в случае с вектором надо постоянно с собой таскать объект-вектор. Всё это решаемо, но может оказаться менее удобным, чем работа с указателем. Дополнительно при увеличении размера идёт зачастую ненужная работа по обнулению. Но в целом, с виду, можно заменять.

На коротком примере проверил максимально разрешённый размер для vector.resize - он совпал с ограничением по realloc'у

Цитата Сообщение от KBEPTMEH Посмотреть сообщение
Так же подчеркнул для себя ряд интересных нюансов в последующих сообщениях.
Всем большое спасибо
Спор, направленный в правильное русло, почти всегда заканчивается кучей полезной информации для прочих читателей

Цитата Сообщение от fasked Посмотреть сообщение
То есть realloc тоже выделяет заведомо больше памяти?
Любой менеджер памяти всегда выделяет заведомо больше памяти. Т.е. если ты будешь 100 раз довыделять по 1 байту, то обращаться 100 раз к Api системы получается слишком дорого. Куда дешевле выходит при первом обращении, например, выделить сразу 4 килобайта памяти, а при последующих 99 довыделениях просто поправить значение текущего размера массива. тот Allocator, который находится в параметре шаблона, можно переопределить на свой и реализовать свою собственную логику выделения памяти.

malloc внутри себя тоже выделяет сразу большой кусок памяти. Это низкоуровневая функция, а потому она умеет работать по конкретным значениям виртуальных адресов и выделяет память с точностью до границы страницы. Ибо аппаратный контроль за допустимой областью памяти делается именно с точностью до страницы
3
27.03.2011, 12:46
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.03.2011, 12:46
Помогаю со студенческими работами здесь

Как удалить элемент из массива и сжать его (без динамического выделения памяти)?
как удалить элемент из массива и сжать его,без динамического выделения памяти

Сумма элементов первой и последней строчки матрицы с использованием динамического выделения памяти
Количество строк и столбцов задается пользователем с клавиатуры. Элементы матрицы разместить в...

Реализовать «массив целых чисел». Обработать ошибки динамического выделения памяти. Переопределить опе
Реализовать класс «массив целых чисел». Обработать ошибки динамического выделения памяти....

Функция динамического выделения памяти
Здравствуйте! Никак не получается реализовать функцию динамического выделения памяти и это ставит...


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru