Местоположение указателей и глобальных переменных в C

Где указатели и глобальные переменные хранятся в C? Они сохраняются в памяти, "куче" или стеке?

13
задан Matthew D. Scholefield 6 May 2015 в 00:01
поделиться

4 ответа

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

25
ответ дан 1 December 2019 в 18:49
поделиться

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

Подробнее здесь .

-2
ответ дан 1 December 2019 в 18:49
поделиться

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

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

6
ответ дан 1 December 2019 в 18:49
поделиться

Compile

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

Линковка

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

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

Загрузка

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

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

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

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

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

8
ответ дан 1 December 2019 в 18:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: