C ++ new / new [], как он распределяет память? - PullRequest
0 голосов
/ 12 декабря 2010

Мне бы хотелось узнать, как эти инструкции распределяют память.

Например, что, если я получил код:

x = new int[5]; 
y = new int[5];

Если они расположены, как это на самом деле выглядит в оперативной памяти? Целый блок, зарезервированный для каждой из переменных или блока (страница памяти или как вы ее называете - размер 4 КБ на 32 бита), используется совместно для 2 переменных?

Я не смог найти ответ на свой вопрос ни в одном руководстве. Спасибо за все ответы.

Я нашел в википедии: Внутренняя фрагментация страниц Редко процессы требуют использования точного количества страниц. В результате последняя страница, вероятно, будет заполнена лишь частично, что приведет к напрасной трате памяти. Таким образом, большие размеры страниц явно увеличивают вероятность потери памяти, так как в основную память загружаются потенциально неиспользуемые части памяти. Меньшие размеры страницы обеспечивают более точное соответствие с фактическим объемом памяти, необходимым для выделения. В качестве примера предположим, что размер страницы составляет 1024 КБ. Если процесс выделяет 1025 КБ, необходимо использовать две страницы, что приводит к 1023 КБ неиспользуемого пространства (при этом одна страница полностью занимает 1024 КБ, а другая только 1 КБ).

И это был ответ на мой вопрос. В любом случае, спасибо, ребята.

Ответы [ 3 ]

4 голосов
/ 12 декабря 2010

Типичная реализация распределителя сначала вызовет операционную систему, чтобы получить огромный блок памяти, а затем, чтобы удовлетворить ваш запрос, предоставит вам часть этой памяти, которая называется suballocation . Если ему не хватит памяти, он получит больше от операционной системы.

Распределитель должен отслеживать как все большие блоки, которые он получил от операционной системы, так и все маленькие блоки, которые он раздавал своим клиентам. Он также должен принимать блоки обратно от клиентов.

Типичный алгоритм перераспределения хранит список возвращаемых блоков каждого размера, называемый freelist , и всегда пытается удовлетворить запрос от freelist, переходя к основному блоку, только если freelist пуст. Этот конкретный метод реализации является чрезвычайно быстрым и достаточно эффективным для средних программ, хотя он обладает ужасными свойствами фрагментации, если размеры запросов повсюду (что не является обычным для большинства программ).

Современные распределители, такие как реализация malloc в GNU, сложны, но были созданы с многолетним опытом и должны считаться настолько хорошими, что очень редко нужно писать собственный специализированный субаллокатор.

4 голосов
/ 12 декабря 2010

Вы не нашли его в руководстве, потому что оно не указано в стандарте. То есть большую часть времени x и y будут располагаться рядом (продолжайте и cout<< hex << их адреса).

Но в стандарте нет ничего такого, на что нельзя положиться.

1 голос
/ 12 декабря 2010

С каждым процессом связаны разные сегменты, которые поделены между адресным пространством процесса: 1) текстовый сегмент :: где размещен ваш код 2) сегмент стека :: стек процесса 3) сегмент данных :: Это место, где "память"новый "зарезервирован.Кроме того, он также хранит инициализированные и неинициализированные статические данные (bss и т. Д.).

Итак, всякий раз, когда вы вызываете новую функцию (которая, я думаю, использует malloc внутри, но новый класс делает ее более безопасной для обработки памяти), онавыделяет указанное количество байтов в сегменте данных.Конечно, адрес, который вы печатаете во время работы программы, является виртуальным и должен быть переведен на физический адрес ... но это не наша головная боль, и блок управления памятью ОС делает это для нас.

...