В нетривиальных программах на C / C ++ обычно невозможно заранее узнать, сколько памяти вам понадобится во время выполнения.Это означает, что даже если ваш компилятор изо всех сил старается, он не всегда может создать программу, которая статически резервирует только необходимый объем памяти.
Современные платформы обычно различают на некотором уровне три типа памяти:
- память, которую ваша программа выделяет и использует на протяжении всей своей продолжительности (статические / глобальные переменные, функции и т. Д.)
- память, которую ваша программа может запросить во время выполнения, используя
malloc
и такие - память стека
Объем статической памяти, в которой нуждается ваша программа, не может быть легко оценен, поскольку она сильно варьируется в зависимости от операционной системы, компилятора, стандартная библиотека и т. д. Однако ваша программа очень мала, поэтому было бы удивительно, если бы ей требовалось больше нескольких килобайт на любой платформе.На платформах, где память особенно ценна, вполне вероятно, что она может составлять всего несколько байтов.
Ваша программа не использует malloc
или другие функции выделения, поэтому ей не требуется такая память.
Память стека - то, где волшебство происходит здесь.Стек - это область памяти, которую программа может использовать (и повторно использовать) при вызове функции.Его размер зависит от платформы (и обычно это где-то документируется), и операционные системы обычно оптимизируют ее использование таким образом, что память не становится доступной для программы до того, как она действительно попытается ее использовать.
Если выне хватает памяти стека, происходит неопределенное поведение.На платформах, где память драгоценна, вы можете испортить какую-то другую часть вашей программы.В наши дни на большинстве современных платформ вместо этого возникает сбой.
Если предположить, что ваша программа не была оптимизирована, а некоторые детали платформы скрыты, использование памяти будет выглядеть примерно так:
- запуск программы
- вы не используете стековую память
- введите
main
: установить фрейм стека (~ 16 байт служебной работы) - вы используете 16 байт стековой памяти
- введите
create_8_bytes
: установить фрейм стека (~ 16 байт служебной деятельности, 8 байт переменных) - выиспользовать 40 байт стековой памяти
- оставить
create_8_bytes
: освободить кадр стека, который create_8_bytes
использовал - вы используете 16 байтов памяти
- enter
create_4_bytes
: установить фрейм стека (~ 16 байт служебных данных, 4 байта переменных) - используется 36 байт памяти
- оставьте
create_4_bytes
: освободите кадр стека - вы используете 16 байт памяти
- введите
puts
(используйте неизвестное количествопамять) - вы используете 16+ ???байт памяти
- оставить
puts
- вы используете 16 байтов стековой памяти
- оставить
main
- вы не используете стековую память
Как видите, объем используемой памяти увеличивается и уменьшается при входе и выходе из функций.
Хотя это обеспечивает правильную интуицию для использования стековой памяти, имейте в виду, что компиляторы, как правило, способны удалять части вашей программы, если они могут доказать, что это не изменит результат.Это означает, что вы можете ожидать, что ваши локальные переменные исчезнут, если вы их не используете, и даже если вы их используете, вполне возможно, что компилятор может использовать другие преобразования, которые позволят переменным вообще не использовать стековую память.Также возможно, что компилятор может использовать стековую память для вещей, которые вы явно не указали.