Указатели в C++
Указатели в C++: адреса памяти, оператор взятия адреса (&), разыменование (*), арифметика указателей и типичные ошибки.
Указатель — переменная, которая хранит адрес в памяти другой переменной. Указатели дают прямой доступ к данным и позволяют эффективно передавать большие объекты.
Адреса и оператор &
Каждая переменная занимает место в памяти и имеет адрес. Оператор & возвращает этот адрес.
#include <iostream>
int main() {
int x = 42;
std::cout << "Значение: " << x << "\n";
std::cout << "Адрес: " << &x << "\n"; // например, 0x7ffee4b2c5ac
return 0;
}
Вывод:
Значение: 42 Адрес: 0x7ffee4b2c5ac
Объявление и разыменование
Указатель объявляют со звёздочкой: int* p. Оператор * перед указателем — разыменование: читаем или пишем значение по адресу.
#include <iostream>
int main() {
int x = 10;
int* p = &x; // p хранит адрес x
std::cout << *p << "\n"; // 10 — читаем через указатель
*p = 99; // меняем x через указатель
std::cout << x << "\n"; // 99 — x изменился!
return 0;
}
Вывод:
10 99
Указатели на массивы
Имя массива — это указатель на его первый элемент. Можно перебирать массив через арифметику указателей.
#include <iostream>
int main() {
int arr[3] = {10, 20, 30};
int* p = arr; // указатель на arr[0]
std::cout << *p << "\n"; // 10
std::cout << *(p + 1) << "\n"; // 20 — следующий элемент
std::cout << *(p + 2) << "\n"; // 30
return 0;
}
Вывод:
10 20 30
new и delete — динамическая память
new выделяет память в куче (heap) и возвращает указатель. delete освобождает её. Без delete — утечка памяти.
#include <iostream>
int main() {
int* p = new int(7); // выделяем и инициализируем
std::cout << *p << "\n"; // 7
delete p; // обязательно освобождаем!
p = nullptr; // обнуляем указатель
// Динамический массив:
int* arr = new int[5]{1, 2, 3, 4, 5};
std::cout << arr[2] << "\n"; // 3
delete[] arr; // для массивов — delete[]
return 0;
}
Вывод:
7 3
В современном C++ предпочитают умные указатели (
std::unique_ptr,std::shared_ptr) вместо «голого»new/delete— они освобождают память автоматически.
Типичные ошибки
- Висячий указатель — обращение к памяти после
delete. После удаления всегда пишитеp = nullptr. - Утечка памяти — забыли вызвать
delete. Используйте умные указатели. - Нулевой указатель — разыменование
nullptrвызывает падение программы. - delete[] vs delete — для массивов нужен
delete[], иначе поведение не определено.
Коротко
&x— адрес переменной;int* p = &x— указатель хранит адрес.*p— разыменование: читаем/пишем значение по адресу.newвыделяет память в куче;deleteосвобождает — всегда в паре.- Для массивов:
new T[n]иdelete[].