Когда выделяется и выделяется память stati c и динамическая c память в C? - PullRequest
1 голос
/ 10 января 2020

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

Stati c выделение памяти - это происходит во время компиляции. Компилятор выделяет необходимую память, необходимую для памяти stati c.

Stati c освобождение памяти - память освобождается автоматически по окончании работы блока / функции (для локальных переменных) или когда вся программа завершил выполнение (для глобальных переменных).

Dynami c выделение памяти - память выделяется во время выполнения, поскольку в данный момент размер ввода неизвестен.

Динамическая память освобождение - память освобождается при выполнении free ().

Это правильно? Я что-то упустил?

Ответы [ 2 ]

4 голосов
/ 10 января 2020

На языке C существует 3 различных типа продолжительности хранения:

  • stati c: время жизни переменной - это время жизни программы. Он выделяется во время загрузки (определяется только во время компиляции) и освобождается только тогда, когда операционная система выгружает программу. Переменные Stati c - это переменные, объявленные вне любых функций, а локальные переменные (объявленные в функции или блоке), имеющие модификатор static
  • automati c: переменные automati c объявлены внутри блока (или функция), без модификатора хранилища. Их время жизни начинается в начале блока c и заканчивается в конце блока c. Они обычно размещаются в начале блока blo c и освобождаются в его конце, но из-за правила «как будто» оптимизирующие компиляторы могли бы распределить их раньше и освободить их позже, например, если блок blo c находится внутри oop.
  • dynamici c: они распределяются вручную через malloc и будут освобождены только free

В общих реализациях системный стек используется для автоматизации c переменные и пул памяти (запрашивая у операционной системы, когда требуется больше памяти) для динамических c переменных, но это детали реализации

При использовании многопоточности четвертый тип длительности хранения доступно: продолжительность хранения потока. Эти переменные объявляются с модификатором класса хранения _Thread_local. Их время жизни - это продолжительность потока, и каждый поток имеет свою собственную копию.

Для обычной реализации они управляются так же, как переменные stati c: они выделяются операционной системой, когда поток создается и восстанавливается (все еще ОС), когда поток заканчивается.


Некоторые замечания относительно ваших формулировок:

Stati c выделение памяти - это происходит во время время компиляции.

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

Stati c освобождение памяти - память освобождается автоматически после завершения работы блока / функции ( для локальных переменных) ...

Существует путаница между областью действия (локальной и глобальной) и продолжительностью хранения. Функция может содержать переменные stati c, что является одной из причин ключевого слова static

Dynami c выделение памяти - память выделяется во время выполнения , поскольку в данный момент размер ввода неизвестен

Это одна из возможных причин для программиста использовать динамическую память c, но могут быть и другие, например, потому что код будет будь таким чище. В частности, динамическая c память - хороший инструмент, когда вы хотите имитировать c объектно-ориентированное программирование на C языке.

0 голосов
/ 10 января 2020

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

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

И освобождение не обязательно означает, что вы предоставляете неиспользуемую память операционной системе. Обычно стандартная библиотека c отслеживает свободные блоки и объединяет их, если это возможно, чтобы не выполнять sbrk или эквивалентный системный вызов в следующий раз, когда вы захотите выполнить mallo c, потому что они относительно дороги. Я считаю, что сильно зависит от реализации библиотеки

...