Сырые указатели (raw pointers) — это переменные, хранящие адреса памяти. Они являются фундаментальным механизмом в C/C++ для работы с динамической памятью и сложными структурами данных.
int* ptr; // Объявление указателя
ptr = new int(42); // Выделение памяти и инициализация
*ptr = 10; // Разыменование и изменение значения
delete ptr; // Освобождение памяти
ptr = nullptr; // Обнуление указателя
// Одиночный объект
MyClass* obj = new MyClass();
delete obj;
// Массив объектов
MyClass* arr = new MyClass[10];
delete[] arr;
int* ptr = (int*)malloc(sizeof(int)*10);
free(ptr);
new
вызывает конструктор, malloc
только выделяет памятьdelete
вызывает деструктор, free
только освобождает памятьnew
бросает исключения, malloc
возвращает NULLvoid leak() {
int* ptr = new int(10);
// забыли delete - утечка
}
int* dangling_ptr() {
int x = 10;
return &x; // возврат указателя на локальную переменную
}
int* ptr = new int(10);
delete ptr;
delete ptr; // Ошибка!
int* arr = new int[10];
delete arr; // Должно быть delete[] !
class SmartPointer {
int* ptr;
public:
explicit SmartPointer(int* p) : ptr(p) {}
```SmartPointer() { delete ptr; }
// ... другие методы
};
// Возвращает владение вызывающему
std::unique_ptr<Resource> createResource();
// Принимает временное владение
void processResource(std::unique_ptr<Resource>&& res);
class ArenaAllocator {
char* pool;
size_t offset;
public:
ArenaAllocator(size_t size) : pool(new char[size]), offset(0) {}
```ArenaAllocator() { delete[] pool; }
template<typename T>
T* allocate(size_t count = 1) {
void* ptr = pool + offset;
offset += sizeof(T)*count;
return static_cast<T*>(ptr);
}
};
char buffer[sizeof(MyClass)];
MyClass* obj = new (buffer) MyClass();
obj->```MyClass(); // Явный вызов деструктора
#include <cstdlib>
void* aligned_alloc(size_t alignment, size_t size);
Низкоуровневые операции:
Оптимизация производительности:
Совместимость с C-библиотеками:
Valgrind:
valgrind --leak-check=full ./my_program
AddressSanitizer:
g++ -fsanitize=address -g program.cpp
Инструменты визуализации:
Резюмируем: работа с сырыми указателями требует дисциплины и четкого понимания модели памяти. В современном C++ предпочтительно использовать умные указатели, но знание ручного управления необходимо для системного программирования, оптимизации и работы с legacy-кодом.