Статические и динамические объекты программ: компиляция против выполнения
Что это такое
Статические объекты - те, чьи свойства (тип, размер памяти, связи)
определяются по тексту программы еще при компиляции и остаются неизменными
до самого конца работы. Компилятор смотрит на int x[10]; и уже знает
про этот массив все: десять целых чисел, ни больше ни меньше.
Динамические объекты - те, чьи свойства или само существование определяются в процессе выполнения (runtime). Сколько элементов будет в массиве, выяснится, когда пользователь введет число; объект появится, когда программа попросит под него память, и исчезнет, когда память освободят.
Зачем это нужно
У каждого подхода свои сильные стороны:
- Статика - надежность и скорость. Компилятор может заранее проверить типы, поймать ошибки до запуска и раз и навсегда распределить память: во время работы на это не тратится ни такта.
- Динамика - гибкость. Программа подстраивается под входные данные неизвестного размера, создает объекты "на лету" и возвращает память, когда объекты больше не нужны.
Как физически организованы статические и динамические объекты программ
- Распределение памяти. Если память под объект выделяет транслятор и ее объем не меняется - объект статический. Если память выделяется во время работы из специальной области - кучи (heap) - и может меняться, объект динамический.
- Уровень изменчивости языка. В статически типизированных языках (C, Pascal) характеристики объектов менять трудно - зато программы быстрые. В языках с неограниченным динамизмом (Python, Lisp) характеристики можно менять свободно прямо во время работы - за счет скорости.
int x[10]; -
получили ровно десять int на все время жизни функции. Чтобы получить
динамический объект в C, память у системы запрашивают вручную.
Оба вида объектов в одной программе на C
#include <stdio.h>
#include <stdlib.h>
int main(void) {
/* Статический объект: размер и тип зафиксированы при компиляции */
int staticArray[5] = {1, 2, 3, 4, 5};
int n = 10; /* размер выясняется в рантайме, например вводится пользователем */
/* Динамический объект: память выделяется во время выполнения, из кучи */
int* dynamicArray = (int*)malloc(n * sizeof(int));
if (dynamicArray != NULL) {
dynamicArray[0] = 42;
/* Динамический объект нужно уничтожить вручную */
free(dynamicArray);
}
return 0;
}
Обратите внимание: у динамического массива нет собственного имени - есть только
указатель dynamicArray, через который к нему можно добраться.
Что такое указатель, разберем в
следующем уроке.
Коротко: главное
- Статический объект: тип, размер и существование известны с этапа компиляции.
- Динамический объект: создается, меняется и уничтожается во время выполнения, живет в куче.
- Статика дает скорость и надежность (проверка типов, память заранее), динамика - гибкость.
- Языки различаются уровнем изменчивости: строгие C и Pascal против динамичных Python и Lisp.
- В C динамические объекты создает malloc, уничтожает free; имени у них нет - только указатель.
Проверьте себя
Программа читает у пользователя число n и вызывает malloc(n * sizeof(int)). Каким получился массив?