Структура памяти программы в C++ делится на несколько сегментов, каждый из которых предназначен для хранения различных типов данных и выполнения определенных функций. Рассмотрим основные сегменты памяти:
1. Сегмент кода (Code Segment)
Также известен как текстовый сегмент. В этом сегменте хранится исполняемый машинный код программы. Обычно он доступен только для чтения, чтобы предотвратить случайную или намеренную модификацию инструкций программы.
2. Сегмент данных (Data Segment)
Этот сегмент делится на два подтипа:
- Сегмент инициализированных данных (Initialized Data Segment): Здесь хранятся глобальные и статические переменные, которые инициализированы значениями, отличными от нуля. Эти переменные сохраняют свои значения на протяжении всего выполнения программы.
- Сегмент неинициализированных данных (BSS Segment): Этот сегмент хранит глобальные и статические переменные, которые инициализированы значениями по умолчанию (обычно нулями). Название BSS происходит от “Block Started by Symbol”.
3. Сегмент стека (Stack Segment)
Стек используется для хранения локальных переменных, параметров функций и адресов возврата. Стек работает по принципу LIFO (Last In, First Out). Когда вызывается функция, ее параметры и локальные переменные помещаются в стек. Когда функция завершает выполнение, эти данные удаляются из стека. Размер стека ограничен, и превышение этого размера может привести к переполнению стека (stack overflow).
4. Сегмент кучи (Heap Segment)
Куча используется для динамического распределения памяти. Память в куче выделяется и освобождается вручную с помощью операторов new
и delete
в C++. Куча предоставляет более гибкое управление памятью, но требует от программиста явного управления памятью, чтобы избежать утечек памяти и других ошибок.
Пример программы
Рассмотрим простую программу на C++, чтобы понять, как различные части памяти используются:
#include <iostream>
int global_var = 10; // глобальная переменная (сегмент инициализированных данных)
static int static_var = 20; // статическая переменная (сегмент инициализированных данных)
void func() {
int local_var = 30; // локальная переменная (стек)
int* dynamic_var = new int(40); // динамическая переменная (куча)
std::cout << "Local variable: " << local_var << std::endl;
std::cout << "Dynamic variable: " << *dynamic_var << std::endl;
delete dynamic_var; // освобождение динамической памяти
}
int main() {
func();
return 0;
}
Размещение переменных в памяти
- global_var: находится в сегменте инициализированных данных.
- static_var: также находится в сегменте инициализированных данных.
- local_var: хранится в стеке.
- dynamic_var: указывает на память, выделенную в куче.