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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.95
KBEPTMEH
0 / 0 / 0
Регистрация: 26.03.2011
Сообщений: 12
26.03.2011, 13:02     Операторы динамического выделения памяти - new/delete #1
Здравствуйте.

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

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

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

Всем заранее спасибо за Ваши ответы и подсказки.
С уважением.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
26.03.2011, 17:01     Операторы динамического выделения памяти - new/delete #21
Цитата Сообщение от slice Посмотреть сообщение
Ты случайно не знаешь, как ведет себя вектор при ресайзе?
А что, вектор уже стал встроенной конструкцией C++?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
slice
32 / 75 / 4
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 17:26     Операторы динамического выделения памяти - new/delete #22
Evg, Что ты подразумеваешь под встроенной конструкцией языка?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
26.03.2011, 17:34     Операторы динамического выделения памяти - new/delete #23
Цитата Сообщение от Evg Посмотреть сообщение
А что, вектор уже стал встроенной конструкцией C++?
не менее встроенная чем malloc
slice
32 / 75 / 4
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 17:36     Операторы динамического выделения памяти - new/delete #24
alex_x_x, вот и я об этом же подумал.
Evg, на вопрос про вектор сможешь ответить?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
26.03.2011, 17:39     Операторы динамического выделения памяти - new/delete #25
Цитата Сообщение от slice Посмотреть сообщение
Evg, Что ты подразумеваешь под встроенной конструкцией языка?
А к чему ты спросил про вектор, когда речь шла об отсутствии встроенной конструкции, являющейся аналогом аналога?

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


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



Цитата Сообщение от Evg Посмотреть сообщение
Да куда уж мне. Это ведь твой интеллектуальный вклад в данную тему кто-то оценил, а не мой
К сожалению этот кто-то передумал и вернул все как было. А если серьезно, ты можешь ответить нормально, без увертываний?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
26.03.2011, 18:34     Операторы динамического выделения памяти - new/delete #27
Цитата Сообщение от slice Посмотреть сообщение
я спросил о возможности использования метода ресайз у вектора как алтернативу реалока
А ты и в правду считаешь, что это альтернатива реаллоку?

Цитата Сообщение от slice Посмотреть сообщение
А если серьезно, ты можешь ответить нормально, без увертываний?
Могу, но зачем? Мы ж вроде как бессмысленно препираемся
slice
32 / 75 / 4
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 18:40     Операторы динамического выделения памяти - new/delete #28
Цитата Сообщение от Evg Посмотреть сообщение
А ты и в правду считаешь, что это альтернатива реаллоку?
да


Цитата Сообщение от Evg Посмотреть сообщение
Могу, но зачем? Мы ж вроде как бессмысленно препираемся
препираться мне надоело
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
26.03.2011, 18:54     Операторы динамического выделения памяти - new/delete #29
То, что возвращает malloc/realloc - это сплошной участок памяти. Эту память действительно можно использовать произвольным образом. То, что работает через контейнер vector - оно только внешне выглядит как сплошной участок. На самом деле это фрагментированные куски памяти, а оператор [] возвращает указатель на нужную запись путём вычисления, в котором из фрагментов находится участок. То, что тебе выдало malloc, грубо говоря, можно копировать через memcpy, а с вектором - нельзя. Обращение к элементу памяти от malloc'а по индексу делается за константное количество операций (адрес + индекс помноженный на sizeof), а обращение к элементу в vector'е - это вычисления. vector - это, грубо говоря, то, о чём написано в конце поста #5
slice
32 / 75 / 4
Регистрация: 04.11.2010
Сообщений: 249
26.03.2011, 19:05     Операторы динамического выделения памяти - new/delete #30
Evg
Я надеюсь ты не шутишь.
Если нет, то ты чертовски заблуждаешься. В векторе все элементы хранятся сподряд. Можно без проблем взять указатель на нулевой элемент и обращаться к другим элементам, прибавляя оффсет.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
26.03.2011, 19:23     Операторы динамического выделения памяти - new/delete #31
Действиетльно, что-то меня проглючило

Добавлено через 12 минут
Действительно, разницы особенно нет. Для vector<char> resize работает раза в два медленнее, чем calloc такого же размера, но это мелочи. С виду вектор действительно является аналогом realloc'а (пусть и не являясь при этом встроенной конструкцией языка)
Saiberg
 Аватар для Saiberg
19 / 19 / 1
Регистрация: 23.09.2010
Сообщений: 193
26.03.2011, 20:04     Операторы динамического выделения памяти - new/delete #32
можно узнать почему malloc встроенная конструкция языка ?
malloc так же как и vector вроде является стандартной библиотекой.

malloc (#include <stdlib.h>)
vector (#include <vector>)
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
26.03.2011, 22:42     Операторы динамического выделения памяти - new/delete #33
Цитата Сообщение от Saiberg Посмотреть сообщение
можно узнать почему malloc встроенная конструкция языка ?
А никто и не говорил, что malloc встроенная. new/delete - встроенные
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,390
27.03.2011, 04:10     Операторы динамического выделения памяти - new/delete #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, если я вообще понял суть обсуждаемого вопроса.
KBEPTMEH
0 / 0 / 0
Регистрация: 26.03.2011
Сообщений: 12
27.03.2011, 11:18  [ТС]     Операторы динамического выделения памяти - new/delete #35
Вот это Вы тему развили
Evg, мне привел пример того, как можно выделить большущий кусок RAM - "дробить" и блоками выделять.
Использую я именно операторы new/delete - мне так удобнее и проще.

То есть вопрос полностью решен
Так же подчеркнул для себя ряд интересных нюансов в последующих сообщениях.
Всем большое спасибо
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
27.03.2011, 12:07     Операторы динамического выделения памяти - new/delete #36
Цитата Сообщение от Nameless One Посмотреть сообщение
Так что vector::resize все же нельзя считать аналогом realloc'a, если я вообще понял суть обсуждаемого вопроса.
кхм, а realloc делает пространственно-временные разрывы? просто делает он тоже самое
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
27.03.2011, 12:13     Операторы динамического выделения памяти - new/delete #37
Цитата Сообщение от alex_x_x Посмотреть сообщение
кхм, а realloc делает пространственно-временные разрывы? просто делает он тоже самое
То есть realloc тоже выделяет заведомо больше памяти?
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
27.03.2011, 12:15     Операторы динамического выделения памяти - new/delete #38
fasked, нет, я про то, что когда не хватает памяти на изменение размера блока - копирует его в другую часть кучи и возвращает новый указатель
про больший резервируемый размер - это вопрос оптимизации
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.03.2011, 12:46     Операторы динамического выделения памяти - new/delete
Еще ссылки по теме:

C++ Сумма элементов первой и последней строчки матрицы с использованием динамического выделения памяти
По поводу динамического выделения памяти C++
Как написать программу для динамического выделения памяти с использованием new C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
27.03.2011, 12:46     Операторы динамического выделения памяти - new/delete #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 внутри себя тоже выделяет сразу большой кусок памяти. Это низкоуровневая функция, а потому она умеет работать по конкретным значениям виртуальных адресов и выделяет память с точностью до границы страницы. Ибо аппаратный контроль за допустимой областью памяти делается именно с точностью до страницы
Yandex
Объявления
27.03.2011, 12:46     Операторы динамического выделения памяти - new/delete
Ответ Создать тему
Опции темы

Текущее время: 17:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru