Где в памяти мои переменные, хранящиеся в C?

Учитывая, что память разделена на четыре сегмента: данные, куча, стек и код, где глобальные переменные, статические переменные, постоянные типы данных, локальные переменные (определенные и объявленные в функциях), переменные (в основной функции), указатели , и динамически распределенное пространство (используя malloc и calloc) сохраняются в памяти?

Я думаю, что они будут распределены следующим образом:

  • Глобальные переменные ——-> данные
  • Статические переменные ——-> данные
  • Постоянные типы данных —–> код
  • Локальные переменные (объявленные и определенные в функциях) ——–> стек
  • Переменные, объявленные и определенные в основной функции —–> куча
  • Указатели (например, char *arr , int *arr ) ——-> куча
  • Динамически выделенное пространство (используя malloc и calloc) ——–> стек

Я имею в виду эти переменные только с точки зрения С.

Пожалуйста, поправьте меня, если я ошибаюсь, поскольку я новичок в C.

Вы получили некоторые из этих прав, но тот, кто написал вопросы, обманул вас хотя бы на один вопрос:

  • глобальные переменные ——-> данные (правильные)
  • статические переменные ——-> данные (правильные)
  • постоянные типы данных —–> код и / или данные. Рассмотрим строковые литералы для ситуации, когда сама константа будет храниться в сегменте данных, а ссылки на нее будут встроены в код
  • локальные переменные (объявленные и определенные в функциях) ——–> stack (correct)
  • переменные, объявленные и определенные в main функции —–> куча также стек (учитель пытался обмануть вас)
  • указатели (ex: char *arr , int *arr ) ——-> данные кучи или стек, в зависимости от контекста. C позволяет объявить глобальный или static указатель, и в этом случае сам указатель попадет в сегмент данных.
  • динамически распределенное пространство (с использованием malloc , calloc , realloc ) ——–> стек кучи

Стоит отметить, что «стек» официально называется «classом автоматического хранения».

Для тех будущих посетителей, которым может быть интересно узнать об этих сегментах памяти, я пишу важные моменты о 5 сегментах памяти в C:

Некоторые хедз-ап:

  1. Всякий раз, когда выполняется программа на С, в ОЗУ для выполнения программы выделяется некоторая память. Эта память используется для хранения часто исполняемого кода (двоичных данных), переменных программы и т. Д. Ниже сегменты памяти говорят о том же:
  2. Обычно существуют три типа переменных:
    • Локальные переменные (также называемые автоматическими переменными в C)
    • Глобальные переменные
    • Статические переменные
    • Вы можете иметь глобальные статические или локальные статические переменные, но три из них являются родительскими.

5 сегментов памяти в C:

1. Сегмент кода

  • Сегмент кода, также называемый текстовым сегментом, представляет собой область памяти, которая содержит часто исполняемый код.
  • Сегмент кода часто доступен только для чтения, чтобы избежать риска переопределения путем программирования ошибок, таких как переполнение буфера и т. Д.
  • Сегмент кода не содержит программных переменных, таких как локальная переменная ( также называемая автоматическими переменными в C ), глобальными переменными и т. Д.
  • На основе реализации C сегмент кода может также содержать литералы строки только для чтения. Например, когда вы выполняете printf("Hello, world") тогда строка «Hello, world» создается в сегменте кода / текста. Вы можете проверить это с помощью команды size в ОС Linux.
  • дальнейшее чтение

Сегмент данных

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

2. Неинициализированный сегмент данных

  • Этот сегмент также известен как bss .
  • Это часть памяти, которая содержит:
    1. Неинициализированные глобальные переменные (включая переменные указателя)
    2. Неинициализированные постоянные глобальные переменные .
    3. Неинициализированные локальные статические переменные .
  • Любая глобальная или статическая локальная переменная, которая не инициализируется, будет храниться в сегменте неинициализированных данных
  • Например: глобальная переменная int globalVar; или статическая локальная переменная static int localStatic; будут сохранены в неинициализированном сегменте данных.
  • Если вы объявите глобальную переменную и инициализируете ее как 0 или NULL тогда все равно она перейдет в неинициализированный сегмент данных или bss.
  • дальнейшее чтение

3. Инициализированный сегмент данных

  • В этом сегменте хранятся:
    1. Инициализированные глобальные переменные (включая переменные указателя)
    2. Инициализированные постоянные глобальные переменные .
    3. Инициализированные локальные статические переменные .
  • Например: глобальная переменная int globalVar = 1; или статическая локальная переменная static int localStatic = 1; будут сохранены в сегменте инициализированных данных.
  • Этот сегмент можно дополнительно classифицировать в инициализированную область только для чтения и инициализированную область чтения-записи . Инициализированные постоянные глобальные переменные войдут в инициализированную область только для чтения, в то время как переменные, значения которых могут быть изменены во время выполнения, войдут в инициализированную область чтения-записи .
  • Размер этого сегмента определяется размером значений в исходном коде программы и не изменяется во время выполнения .
  • дальнейшее чтение

4. Сегмент стека

  • Сегмент стека используется для хранения переменных, которые создаются внутри функций ( функция может быть основной или определяемой пользователем функцией ), переменная типа
    1. Локальные переменные функции (включая переменные указателя)
    2. Аргументы, переданные функции
    3. Обратный адрес
  • Переменные, хранящиеся в стеке, будут удалены, как только закончится выполнение функции.
  • дальнейшее чтение

5. Сегмент кучи

  • Этот сегмент предназначен для поддержки распределения динамической памяти. Если программист хочет выделить некоторую память динамически, то в C это делается с использованием методов malloc , calloc или realloc .
  • Например, когда int* prt = malloc(sizeof(int) * 2) тогда будет выделено восемь байтов в куче, а адрес памяти этого местоположения будет возвращен и сохранен в переменной ptr . Переменная ptr будет либо в стеке, либо в сегменте данных в зависимости от способа его объявления / использования.
  • дальнейшее чтение

Исправлены неправильные предложения

 constant data types -----> code //wrong 

локальные постоянные переменные —–> стек

инициализированная глобальная постоянная переменная —–> сегмент данных

неинициализированная глобальная постоянная переменная —–> bss

 variables declared and defined in main function -----> heap //wrong 

переменные, объявленные и определенные в основной функции —–> стек

 pointers(ex:char *arr,int *arr) -------> heap //wrong dynamically allocated space(using malloc,calloc) --------> stack //wrong 

указатели (ex: char * arr, int * arr) ——-> размер этой переменной указателя будет в стеке.

Подумайте, что вы распределяете память из n байтов (используя malloc или calloc ) динамически, а затем указываете на переменную указателя. Теперь, когда n байтов памяти находится в куче, а переменная указателя возвращает 4 байта (если 64-разрядная машина 8 байтов), которая будет в стеке, чтобы сохранить начальный указатель n байтов памяти.

Примечание. Переменные указателя могут указывать на память любого сегмента.

 int x = 10; void func() { int a = 0; int *p = &a: //Now its pointing the memory of stack int *p2 = &x; //Now its pointing the memory of data segment chat *name = "ashok" //Now its pointing the constant string literal //which is actually present in text segment. char *name2 = malloc(10); //Now its pointing memory in heap ... } 

динамически распределенное пространство (используя malloc, calloc) ——–> куча

Популярная архитектура настольных систем делит виртуальную память процесса на несколько сегментов :

  • Текстовый сегмент: содержит исполняемый код. Указатель команд принимает значения в этом диапазоне.

  • Сегмент данных: содержит глобальные переменные (т.е. объекты со статической связью). Разделенные в данные только для чтения (такие как строковые константы) и неинициализированные данные («BSS»).

  • Секция стека: содержит динамическую память для программы, то есть бесплатное хранилище («куча») и локальные фреймы стека для всех streamов. Традиционно стек C и куча C приходили в сегмент стека с противоположных концов, но я считаю, что практика была оставлена, потому что она слишком опасна.

Программа AC обычно помещает объекты со статическим временем хранения в сегмент данных, динамически распределенные объекты в свободном хранилище и автоматические объекты в стеке вызовов streamа, в котором он живет.

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

Я имею в виду эти переменные только с точки зрения С.

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

указатели (например: char * arr, int * arr) ——-> куча

Нет, они могут находиться в стеке или в сегменте данных. Они могут указывать в любом месте.

  • Переменные / автоматические переменные —> раздел стека
  • Динамически распределенные переменные —> секция кучи
  • Инициализированные глобальные переменные -> раздел данных
  • Неинициализированные глобальные переменные -> раздел данных (bss)
  • Статические переменные -> раздел данных
  • Строковые константы -> раздел текста / код
  • Функции -> раздел текста / код
  • Текстовый код -> раздел текста / раздел кода
  • Регистры -> регистры CPU
  • Входы командной строки -> раздел окружения / командной строки
  • Переменные среды -> раздел защиты окружающей среды / командной строки
  • Разница между и
  • Интерфейсы Java и типы возврата
  • Вычисление переменной с использованием переменной типа
  • Есть ли 128-битное целое число в C ++?
  • Создание серии дат - использование типа даты в качестве входных данных
  • динамический тип объекта
  • Какова цель Rank2Types?
  • почему byte + = 1 компилировать, но byte = byte + 1 нет?
  • Итерация по интерфейсу
  • Почему streamи C ++ используют char вместо unsigned char?
  • Как написать функцию для общих чисел?
  • Interesting Posts

    Тестирование модhive Android Studio: чтение данных (ввода)

    Как понять и использовать “, в JavaFX?

    Расширение не может содержать хранимое свойство, но почему статическое разрешено

    MediaStore – Uri для запроса всех типов файлов (носителей и носителей)

    В Firefox я случайно нажал «Начать новую сессию» после сбоя. Как я могу вернуть все свои вкладки?

    Как я могу воспроизвести FLV-файл в Windows Media Player?

    Как выборочно объединить или выбрать изменения из другого филиала в Git?

    Приложение WPF, в котором есть только значок в трее

    Почему нам нужно указывать размер столбца при передаче 2D-массива в качестве параметра?

    c ++ –

    Будет ли больше RAM или больше CPU лучше для NAS (сетевой диск)?

    Может ли x86 переупорядочить узкий магазин с более широкой нагрузкой, которая полностью его содержит?

    Автоматическое изменение времени на основе текущего местоположения

    Одновременно используйте беспроводные и проводные соединения

    CIFS через AnyConnect, Mac для Linux = Коррумпированные файлы

    Давайте будем гением компьютера.