2010-06-24 4 views
13

Где указатели и глобальные переменные хранятся в C? Сохранятся ли они в памяти, куче или стеке?Расположение указателей и глобальные переменные в C

+3

Почему считаются отдельные указатели; в конце концов, указатель является переменной ... – ShinTakezou

+0

Возможно, он не имел в виду указатели, но указатели на объекты указывали? –

+0

Да, это то, что я имею в виду, объекты, которые указываются указателями, а не указатели, поскольку это только локальные переменные (в основном), которые помещаются в стек. –

ответ

22

Глобальные переменные могут находиться в нескольких местах, в зависимости от того, как они настроены - например, const глобальные переменные могут находиться в разделе только для чтения исполняемого файла. «Нормальные» глобалы находятся в разделе «чтение-запись» исполняемого файла. Они вообще не находятся в куче или в стеке. Указатели - это всего лишь тип переменной, поэтому они могут быть там, где вы хотите, чтобы они были (в куче, если вы их malloc(), в стеке, если они являются локальными переменными или в разделе данных, если они глобальны).

+0

«на куче, если вы malloc» Указатель указывает на кучу, а не на то, что указатель имеет свой адрес в куче справа? –

+0

Нет, сам указатель также может находиться в куче. Это просто переменная. –

+0

Хорошо. Это верно - только то, что утверждение несколько неоднозначно при первом чтении. Чтобы было ясно {// блок- INT ** р = (интермедиат **) таНос (SizeOf (INT *). // Здесь указатель * р на куче, но р на стек междунар * p = (int *) malloc (sizeof (int); // Здесь p является указателем и находится в стеке и указывает на место кучи. } –

6

Глобальные переменные обычно хранятся в сегменте данных приложения.

Указатели не хранятся иначе, чем другие переменные (например, если у вас есть локальная переменная типа int*, она будет храниться в стеке, как и любая другая локальная переменная).

-2

Память через malloc() взята из кучи. Это обеспечивает указатель на память.

Дополнительная информация here.

+0

Этот ответ не связан с тем, что пользователь спросил. Во-первых, вы не говорите о глобальных переменных. Затем вы приходите сюда, чтобы поговорить о 'malloc()', и здесь дело не в этом. Указатели не связаны с 'malloc()', вы можете отлично иметь указатель, указывающий на адрес стека. –

8

Compile

Когда файл компилируется, переменные с «длительность программы» (статические или глобальные переменные), которые определены в этой «единицы компиляции» (грубо говоря, «C файла») определить, сколько глобальное пространство, которое требуется этой программе, и как оно инициализируется.

Link

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

Для нулевых инициализированных или неинициализированных глобальных данных сохраняется только объем пространства, необходимого для таких данных. Для инициализированных данных сохраняются начальные значения.

нагрузки

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

Динамические библиотеки

Если ваш код в виде динамической библиотеки, компоновщик не может знать, где он поставит глобальные данные. В этом случае он создает разделы в библиотеке, чтобы указать, где ссылки на глобальные данные, и загрузчик позаботится об изменении ссылок, чтобы указать на нужное место, когда загружает файл (вот почему вы проходите -fPIC в командной строке gcc для dll).Но поскольку это выполняется во время загрузки, к моменту запуска вашей программы размещение данных известно, поэтому загрузчик знает, где эти данные будут указателями на глобальные данные, все равно могут выступать в качестве констант в вашей программе.

Динамическая загрузка

Линкуя динамически в библиотеке DLL, загрузчик не знает об этом, поэтому вы должны вызывать функции, которые знают, как загрузить DLL и получить адрес его экспортируемых данных и функций ,

4

Все распределения, выполняемые malloc(), calloc() или realloc(), хранятся в куче, а все локальные переменные хранятся в стеке.

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

Смежные вопросы