Разница между статическим распределением памяти и динамическим распределением памяти - PullRequest
71 голосов
/ 05 декабря 2011

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

Не могли бы вы объяснить это на каком-нибудь примере?

Ответы [ 7 ]

96 голосов
/ 03 апреля 2013

Это стандартный вопрос интервью:

Динамическое выделение памяти

Распределяется ли память во время выполнения с использованием calloc(), malloc() и друзей.Иногда ее также называют «кучной» памятью, хотя она не имеет ничего общего со структурой данных кучи ref .

int * a = malloc(sizeof(int));

Память кучипостоянный до вызова free().Другими словами, вы управляете временем жизни переменной.

Автоматическое выделение памяти

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

int a = 43;

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

Статическое выделение памяти

Распределение во время компиляции и время жизни переменнойв статической памяти время жизни программы .

В C статическая память может быть выделена с помощью ключевого слова static.Область действия - только единица компиляции.

Все становится интереснее , когда ключевое слово extern считается .Когда переменная extern определена как , компилятор выделяет для нее память.Когда extern переменная объявлена ​​, компилятор требует, чтобы переменная была определена в другом месте.Неспособность объявить / определить extern переменные вызовет проблемы со связыванием, в то время как неудача в объявлении / определении static переменных вызовет проблемы с компиляцией.

в области видимости файла, ключевое слово static является необязательным (вне функции):

int a = 32;

Но не в области действия функции (внутри функции):

static int a = 32;

Технически, extern и static являются двумя отдельными классами переменных в C.

extern int a; /* Declaration */
int a; /* Definition */

Регистровая память

Последний класс памяти является переменными регистра.Как и ожидалось, переменные регистра должны быть размещены в регистре процессора, но решение фактически остается за компилятором.Вы не можете превратить переменную регистра в ссылку, используя address-of.

register int meaning = 42;
printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */

Большинство современных компиляторов умнее, чем вы, выбираете, какие переменные следует помещать в регистры:)

Ссылки:

Замечания о статическом распределении памяти

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

Лучше подумать , что выделение статической памяти обрабатывается компилятором , а не , выделенным во время компиляции . Например, компилятор может создать большой раздел data в скомпилированном двоичном файле, и когда программа загружается в память, адрес в сегменте data программы будет использоваться в качестве расположения выделенной памяти. Это имеет явный недостаток - делать скомпилированный двоичный файл очень большим, если используется много статической памяти. Можно написать двоичный файл размером в несколько гигабайт, сгенерированный из менее чем полдюжины строк кода. Другим вариантом для компилятора является внедрение кода инициализации, который будет распределять память каким-либо другим способом до выполнения программы. Этот код будет отличаться в зависимости от целевой платформы и ОС. На практике современные компиляторы используют эвристику, чтобы решить, какой из этих параметров использовать. Вы можете попробовать это самостоятельно, написав небольшую C-программу, которая выделяет большой статический массив из элементов 10k, 1m, 10m, 100m, 1G или 10G. Для многих компиляторов размер двоичного файла будет расти линейно с размером массива, и после определенной точки он снова сократится, поскольку компилятор использует другую стратегию размещения.

74 голосов
/ 05 декабря 2011

Существует три типа распределения: статическое, автоматическое и динамическое.

Статическое распределение означает, что память для ваших переменных выделяется при запуске программы.Размер фиксируется при создании программы.Он применяется к глобальным переменным, переменным области видимости файла и переменным, квалифицированным как static, определенным внутри функций.

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

void func() {
    int i; /* `i` only exists during `func` */
}

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

int* func() {
    int* mem = malloc(1024);
    return mem;
}

int* mem = func(); /* still accessible */

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

free(mem);
3 голосов
/ 05 декабря 2011

Статическое выделение памяти:

  • Переменные распределяются навсегда
  • Распределение сделано до выполнения программы
  • Он использует структуру данных, называемую стек для реализации статического выделения
  • Менее эффективно
  • Существует нет возможности повторного использования памяти

Динамическое выделение памяти:

  • Распределение переменных только , если программный модуль становится активным
  • Распределениесделано во время выполнения программы
  • Для реализации динамического выделения используется структура данных, называемая heap
  • Более эффективно
  • Есть многоразовость памяти .Память может быть освобождена, когда не требуется
2 голосов
/ 05 декабря 2011

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

Динамическое выделение памяти: Для динамического получения памяти используются такие функции, как malloc () или calloc (). Если эти функции используются для динамического получения изначения, возвращаемые этими функциями, присваиваются переменным-указателям, такие назначения известны как динамическое распределение памяти. Память определяется во время выполнения.

1 голос
/ 04 января 2013

Разница между РАСПРЕДЕЛЕНИЕМ СТАТИЧЕСКОЙ ПАМЯТИ & РАСПРЕДЕЛЕНИЕ ДИНАМИЧЕСКОЙ ПАМЯТИ

Память выделяется до начала выполнения программы (Во время компиляции).
Память выделяется при выполнении программы.

Во время выполнения не выполняются действия по выделению или освобождению памяти.
Привязки памяти устанавливаются и уничтожаются во время выполнения.

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

Реализуется с использованием стеков и куч.
Реализовано с использованием сегментов данных.

Указатель необходим для доступа к переменным.
Нет необходимости в динамически размещаемых указателях.

Более быстрое выполнение, чем Dynamic.
Более медленное выполнение, чем статическое.

Требуется больше памяти.
Требуется меньше памяти.

0 голосов
/ 18 апреля 2017

Статическая память выделяется памяти перед выполнением программы во время компиляции.Распределение динамической памяти - это выделенная память во время выполнения программы во время выполнения.

0 голосов
/ 05 декабря 2011

Статическое выделение памяти.Выделенная память будет в стеке.

int a[10];

Динамическое выделение памяти.Выделенная память будет в куче.

int *a = malloc(sizeof(int) * 10);

, а последняя должна быть свободна d, поскольку в C. нет сборщика мусора (GC).

free(a);
...