Есть ли способ получить диапазон адресов памяти, которые доступны в куче? - PullRequest
4 голосов
/ 09 августа 2011

Мне кажется, что так работает память в C ++:

Если вы используете new, то вы просите реализацию компилятора дать вам немного памяти (любой памяти) из кучи.

Если вы используете новый синтаксис размещения, вы просите перераспределить определенную область памяти, адрес которой вы уже знаете (давайте просто предположим, что это также из кучи), которая, вероятно, также была первоначально выделена из new оператор в какой-то момент.

Мой вопрос такой:

Есть ли способ узнать, какие области памяти доступны вашей программе a priori (т.е. без перераспределения памяти из кучи, уже предоставленной вам оператором new)?

Является ли память в куче смежной? Если да, то можете ли вы узнать, где это начинается и где заканчивается?

p.s. Просто пытаюсь максимально приблизиться к металлу как можно быстрее ...

Ответы [ 4 ]

5 голосов
/ 09 августа 2011

Не переносимым способом.Современные операционные системы, как правило, используют пейджинг (иначе говоря, виртуальную память), поэтому объем доступной памяти не является вопросом, на который легко ответить.

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

2 голосов
/ 09 августа 2011

Память, доступная вашей программе «априори», содержит переменные, которые вы определили. Компилятор точно рассчитал, сколько нужно программе. Нет ничего «лишнего», что вы можете использовать для чего-то другого.

Новые объекты, которые вам нужно создать динамически, выделяются из свободного хранилища (он же куча), возможно, с помощью new, но чаще с использованием контейнеров из библиотеки, таких как std::vector.

В стандарте языка ничего не говорится о том, как это работает, и о том, как его можно использовать.

1 голос
/ 09 августа 2011

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

Однако, байты в одномоментном выделении в new гарантированно будет непрерывным, поэтому если вы сделаете

int *foo = new int[1024 * 1024] 

, вы получите миллион смежных слов.

Если вам действительно нужно большое непрерывное распределение, вам, вероятно, потребуется использовать для этого функции, специфичные для операционной системы (если кто-то не спрятал это за библиотекой Boost, о которой я не знаю).В Windows VirtualAlloc () .В POSIX mmap () .

1 голос
/ 09 августа 2011

Это очень сложный вопрос. В современной операционной системе есть такая подсистема, как менеджер памяти. Когда ваша программа выполняет оператор new, есть две опции:

  • если для программы достаточно памяти, вы получаете указатель на память в куче вашей программы
  • если памяти недостаточно, выполнение передается диспетчеру памяти операционной системы, и он решает, что делать: выделять больше памяти для вашей программы (скажем, она изменит размер вашей кучи) или отказать и выбросить исключение.

Есть ли способ узнать, какие области памяти доступны вашей программе априори (т.е. без перераспределения памяти из кучи, уже выделенной вам новым оператором)?

Хочу подчеркнуть, что это зависит от версии ОС и среды.

Является ли память в куче смежной?

Нет, это может быть несмежно.

...