Проверяет понимание указателей в C/C++ и их способности ссылаться на объекты в разных областях памяти.
Указатель — это переменная, которая хранит адрес другой переменной или объекта в памяти. Сама память в программе делится на несколько областей: стек (stack), куча (heap), глобальная/статическая память и код. Указатель не привязан к конкретной области — он просто содержит числовой адрес, который может ссылаться на любую из них.
Когда вы берёте адрес локальной переменной, указатель указывает на стек. Например:
void func() {
int x = 42;
int* ptr = &x; // ptr указывает на стек
}Здесь ptr хранит адрес переменной x, которая расположена в стеке. Это допустимо, но важно помнить, что после выхода из функции стековая память может быть перезаписана, поэтому указатель становится невалидным.
Когда вы выделяете память динамически, указатель ссылается на кучу. В C это делается через malloc, в C++ — через new:
int* ptr = (int*)malloc(sizeof(int)); // C
*ptr = 10;
free(ptr); // освобождаем
int* ptr2 = new int(20); // C++
delete ptr2;Здесь ptr и ptr2 указывают на объекты в куче. Куча существует до тех пор, пока вы явно не освободите память, поэтому указатели на кучу могут жить дольше, чем указатели на стек.
Указатели на стек часто используются для передачи параметров по ссылке или для оптимизации, когда нужно избежать копирования. Указатели на кучу — основа динамических структур данных (связные списки, деревья) и работы с большими объёмами данных, размер которых неизвестен на этапе компиляции.
Указатель — универсальный инструмент, который может ссылаться на любую область памяти. Главное — следить за временем жизни объекта, на который он указывает, чтобы избежать висячих указателей и утечек памяти. Используйте указатели на стек для быстрых локальных операций, а на кучу — для долгоживущих или динамических данных.