Проблемы размещения памяти в C (64-разрядная версия) - PullRequest
0 голосов
/ 20 февраля 2019

Я хотел понять, как работает программа «С», и сохранить данные в машине.Итак, я посмотрел на Memory Layout C из здесь и следовал тем же инструкциям на моей машине, которая является 64-битной.

Сначала, когда я написал программу (main имеет только return 0;) и использовал команду size для исполняемого файла: она показала большую разницу как в текстовом, так и в сегментах данных.

text    data    bss     dec     hex     filename
10648   2400    2640    15688   3d48    33.exe

Но на упомянутом выше веб-сайте было показано:

text    data    bss     dec     hex     filename
960     248     8       1216    4c0     memory-layout

Первый вопрос: Какие факторы (аппаратное / программное обеспечение) отвечают завыделение памяти?.А что означает dec в макете?/ Вопрос заканчивается здесь

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

для этого кода:

#include <stdio.h> 
int global;  
int main(void) {
    //static int x;
    return 0; 
} 

Я получил вывод как:

text    data    bss     dec     hex     filename
10648   2400    2656    15704   3d48    33.exe

Это потому, что я объявил (не инициализирован) глобальная переменная, и поэтому в bss был добавлен 16 байтов (int-64bit) блока памяти, поэтому из 2640 (первый пример) стало 2656. Я понимаю это.

Q2: Но когда я добавляю static int x, он больше не добавляет блок памяти к bss.Ожидается ли это?

text    data    bss     dec     hex     filename
10648   2400    2656    15704   3d48    33.exe 

Q3 : И, наконец, когда я инициализирую глобальную переменную с 20, data увеличивается (ожидается), а dec также увеличивается, почему?

text    data    bss     dec     hex     filename
10648   2416    2656    15720   3d48    33.exe

Я знаю, что задавал много вопросов здесь, но я хотел точно знать, как это управление памятью работает в C.

Arigato:)

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Вот краткое резюме:

  • исполняемый код, строковые литералы и константные глобальные переменные загружаются в сегмент text , который доступен только для чтения впамять загрузчиком программ ОС в системах, которые ее поддерживают.

  • глобально инициализируемые модифицируемые объекты и локальные инициализированные объекты, объявленные с хранилищем static, загружаются в сегмент data .

  • неинициализированные модифицируемые глобальные объекты и неинициализированные локальные static объекты размещены в сегменте bss , которого нет в исполняемом файле.

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

  • В столбце dec указан общий размер программного кода и данных: сумма text , data и bss .Сюда не входят память, выделенная во время запуска, пространство стека и данные, динамически выделяемые из кучи или использующие другие специфические для ОС методы.

  • hex - шестнадцатеричное представлениеиз dec .

Эти значения варьируются в зависимости от операционной системы, компилятора, настроек компилятора и библиотек.На веб-сайте показаны выходные данные системы, в которой работает CentOS, возможно, в 32-разрядном режиме.Обратите внимание, как одна и та же программа выдает гораздо большие значения для всех сегментов, в основном из-за разного кода запуска библиотеки C.Сама функция main должна использовать от нескольких байтов до максимум нескольких десятков в зависимости от параметров компиляции.

Размер исполняемого файла отличается от dec , поскольку он не содержитданные bss , но содержат другую информацию о том, как загрузить программу: размеры и расположение различных сегментов, ссылки на динамические библиотеки и символы для ссылки на них, отладочную информацию и т. д.

При добавлении глобальной переменной bss увеличивается, если она не инициализирована, в противном случае data увеличивается.Когда вы добавляете локальную переменную, то же самое происходит, если она статическая.

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

Современные операционные системы обрабатывают гораздо больше сегментов и сложностей, связанных с исполняемыми программами, приведенный выше упрощенный подход, который моделирует структуру памяти исполняемого файла.программы в ранних системах Unix в течение 1970-х и 1980-х годов.Имена предшествуют Unix почти на 2 десятилетия.Более подробную информацию можно отобразить с помощью утилит objdump и nm .

Подробное объяснение имен стандартных сегментов Unix можно прочитать здесь:

текст : https://en.wikipedia.org/wiki/Code_segment

data : https://en.wikipedia.org/wiki/Data_segment

bss : https://en.wikipedia.org/wiki/.bss

0 голосов
/ 20 февраля 2019

Какие факторы (аппаратное / программное обеспечение) отвечают за распределение памяти?А что означает dec в компоновке:

Ваша программа во время работы делится на множество разделов.stack содержит локальные переменные.bss data содержит неинициализированные глобальные переменные.initialized data содержит инициализированные глобальные переменные.text содержит ваш текст (код).dec это сумма text, bss, data

Но когда я добавляю static int x, он больше не добавляет блок памяти в bss. Ожидается ли это?

Оставьте его неинициализированным, затем он добавит.

Перед добавлением статической переменной:

   text    data     bss     dec     hex filename
   1099     544       8    1651     673 a.out

После добавления статической переменной:

   text    data     bss     dec     hex filename
   1099     544      16    1659     67b a.out

И, наконец, когда я инициализирую глобальную переменную 20, данные увеличиваются (ожидаются), а dec также увеличивается.Почему?

Потому что dec - это сумма text, data, bss

...