Разница между статическим выделением памяти и динамическим выделением памяти
Я хотел бы знать, в чем разница между статическим выделением памяти и динамическое выделение памяти?
не могли бы вы объяснить это на каком-нибудь примере?
7 ответов:
существует три типа распределения - статическое, автоматическое и динамическое.
Статического Распределения означает, что память для переменных выделяется при запуске программы. Размер фиксируется при создании программы. Он применяется к глобальным переменным, переменным области действия файла и переменным, квалифицированным с помощью
static
определена внутри функции.автоматическое выделение памяти происходит (не-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);
это стандартный вопрос интервью:
динамическое выделение памяти
выделяется память во время выполнения с помощью
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 */
Зарегистрироваться
последний класс памяти-это переменные 'register'. Как и ожидалось, регистровые переменные должны быть выделены на a Регистр процессора, но решение фактически остается за компилятором. Вы не можете превратить переменную регистра в ссылку с помощью address-of.
register int meaning = 42; printf("%p\n",&meaning); /* this is wrong and will fail at compile time. */
большинство современных компиляторов умнее вас в выборе, какие переменные должны быть помещены в регистры:)
ссылки:
- руководство по libc
- К&Р язык программирования C, Добавление А, Раздел 4.1,"Класс Хранения". ( PDF)
- стандарт C11 раздел 5.1.2, 6.2.2.3
- Википедия также имеет хорошие страницы на статическое выделение памяти,Динамическое Выделение Памяти и автоматическое выделение памяти
- The C страница динамического выделения памяти Википедии
- этой Справочник По Управлению Памятью имеет более подробную информацию о базовых реализациях для динамического выделения.
примечания по статическому распределению памяти
несколько запутанно говорить, что статическая память выделяется во время компиляции, особенно если мы начинаем считать, что машина компиляции и хост-машина могут быть разными или даже не быть на одной архитектуре.
может быть, лучше думать что выделение статической памяти обрабатывается компилятором, а не выделяется в время компиляции. Например компилятор может создать большой
data
раздел в скомпилированном двоичном файле и когда программа загружается в память, адрес внутриdata
сегмент программы будет использоваться в качестве местоположения выделяемой памяти. Это имеет заметный недостаток в том, что скомпилированный двоичный файл очень большой, если используется много статической памяти. Можно написать гигабайты бинарных созданные из менее, чем полутора десятков строк кода. Другой вариант для компилятор для введения кода инициализации, который будет выделять память каким-либо другим способом перед выполнением программы. Этот код будет отличаться в зависимости от целевой платформы и ОС. На практике современные компиляторы используют эвристику, чтобы решить, какой из этих вариантов использовать. Вы можете попробовать это самостоятельно, написав небольшую программу C, которая выделяет большой статический массив из 10k, 1m, 10m, 100m, 1G или 10G элементов. Для многих компиляторов двоичный размер будет расти линейно с размером массива, и после определенного момента он снова сократится, поскольку компилятор использует другую стратегию выделения.
динамическое выделение памяти - память выделяется во время выполнения программы в куче. Это используется, когда объем(размер) памяти является переменной и известен только во время выполнения. Динамическое распределение достигается с помощью определенных функций, таких как malloc (), calloc (), realloc (), free в C и "new", "delete" в C++.
Статическое Выделение Памяти - память, выделенная во время компиляции в стеке или других сегментах данных. Это используется, когда объем(размер) памяти статический/постоянный и известен во время компиляции.
статическое выделение памяти: компилятор выделяет необходимое пространство памяти для объявленного variable.By используя адрес оператора,получают зарезервированный адрес и этот адрес может быть назначен переменной указателя.Поскольку большая часть объявленной переменной имеет статическую память, Этот способ присвоения значения указателя переменной указателя называется статическим выделением памяти. память назначается во время компиляции.
динамической памяти распределение: Он использует такие функции, как malloc( ) или calloc( ) для динамического получения памяти.Если эти функции используются для динамического получения памяти и значения, возвращаемые этими функциями, сопоставляются переменным указателя, такие назначения называются динамическим выделением памяти.память определяется во время выполнения.
статическое выделение памяти. Выделяется память в стеке.
int a[10];
динамическое выделение памяти. Выделяется память в куче.
int *a = malloc(sizeof(int) * 10);
и последнее должно быть свободныйd так как нет сборщика мусора (GC) в C.
free(a);
разницу между СТАТИЧЕСКОЕ ВЫДЕЛЕНИЕ ПАМЯТИ & ДИНАМИЧЕСКОЕ ВЫДЕЛЕНИЕ ПАМЯТИ
память выделяется до начала выполнения программы (во время компиляции.)
Память выделяется во время выполнения программы.во время выполнения не выполняются действия по выделению или освобождению памяти.
Привязки памяти устанавливаются и уничтожаются во время выполнения.переменные остаются постоянно выделяется.
Выделяется только при активном программном блоке.реализовано с использованием стеков и куч.
Реализовано с использованием сегментов данных.указатель необходим для доступа к переменным.
Нет необходимости в динамически выделенных указателях.более быстрое выполнение, чем динамическое.
Медленнее, чем статические.требуется больше места в памяти.
Требуется меньше места в памяти.