maestro7it_education

Форк
0

README.md

6️⃣ Указатели и работа с памятью

Указатели в C++ — это переменные, которые хранят адреса других переменных.

Они позволяют вам управлять памятью более гибко и эффективно.

Понимание указателей и работы с памятью критично для написания производительных и безопасных программ.

1. Основы указателей

Объявление и инициализация указателя

Указатель объявляется с использованием оператора *, инициализируется адресом переменной с помощью оператора &.

#include <iostream>
int main() {
int value = 10;
int *ptr = &value; // Объявление указателя и инициализация адресом переменной value
std::cout << "Значение переменной: " << value << std::endl;
std::cout << "Адрес переменной: " << &value << std::endl;
std::cout << "Значение указателя: " << ptr << std::endl;
std::cout << "Значение, на которое указывает указатель: " << *ptr << std::endl;
return 0;
}

Операция разыменования указателя

Операция разыменования указывает на значение, хранящееся по адресу, на который указывает указатель. Используется оператор *.

#include <iostream>
int main() {
int value = 10;
int *ptr = &value;
*ptr = 20; // Изменение значения переменной через указатель
std::cout << "Новое значение переменной: " << value << std::endl;
return 0;
}

2. Динамическое выделение памяти

Для работы с динамической памятью используются операторы new и delete.

Они позволяют выделять и освобождать память во время выполнения программы.

Выделение памяти с помощью new

Оператор new выделяет память на куче и возвращает указатель на неё.

#include <iostream>
int main() {
int *ptr = new int; // Выделение памяти для одного целого числа
*ptr = 30;
std::cout << "Значение: " << *ptr << std::endl;
delete ptr; // Освобождение памяти
return 0;
}

Выделение массива с помощью new

Оператор new[] выделяет память для массива.

#include <iostream>
int main() {
int size = 5;
int *arr = new int[size]; // Выделение памяти для массива целых чисел
for (int i = 0; i < size; ++i) {
arr[i] = i * 10;
}
for (int i = 0; i < size; ++i) {
std::cout << "arr[" << i << "] = " << arr[i] << std::endl;
}
delete[] arr; // Освобождение памяти для массива
return 0;
}

Освобождение памяти с помощью delete

Оператор delete освобождает ранее выделенную память.

#include <iostream>
int main() {
int *ptr = new int(40); // Выделение памяти и инициализация
std::cout << "Значение: " << *ptr << std::endl;
delete ptr; // Освобождение памяти
return 0;
}

3. Указатели и массивы

Массивы и указатели тесно связаны в C++.

Имя массива является указателем на первый элемент массива.

#include <iostream>
int main() {
int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr; // Указатель на первый элемент массива
for (int i = 0; i < 5; ++i) {
std::cout << "arr[" << i << "] = " << *(ptr + i) << std::endl;
}
return 0;
}

4. Умные указатели (C++11 и позже)

В C++11 введены умные указатели, которые управляют временем жизни объектов и помогают избежать утечек памяти.

Самые популярные умные указатели — это std::unique_ptr, std::shared_ptr и std::weak_ptr.

std::unique_ptr

std::unique_ptr обеспечивает владение объектом с единственным указателем.

При уничтожении std::unique_ptr автоматически освобождает память.

#include <iostream>
#include <memory> // Для std::unique_ptr
int main() {
std::unique_ptr<int> ptr = std::make_unique<int>(50); // Выделение и инициализация памяти
std::cout << "Значение: " << *ptr << std::endl;
// Память освобождается автоматически при выходе из области видимости
return 0;
}

std::shared_ptr

std::shared_ptr позволяет нескольким указателям разделять владение одним объектом.

Память освобождается, когда последний std::shared_ptr, владеющий объектом, выходит из области видимости.

#include <iostream>
#include <memory> // Для std::shared_ptr
int main() {
std::shared_ptr<int> ptr1 = std::make_shared<int>(60);
std::shared_ptr<int> ptr2 = ptr1; // Совместное владение
std::cout << "Значение через ptr1: " << *ptr1 << std::endl;
std::cout << "Значение через ptr2: " << *ptr2 << std::endl;
// Память освободится после выхода из области видимости последнего shared_ptr
return 0;
}

std::weak_ptr

std::weak_ptr используется вместе с std::shared_ptr для наблюдения за объектом без увеличения счётчика ссылок, что помогает избежать циклических ссылок.

#include <iostream>
#include <memory> // Для std::weak_ptr и std::shared_ptr
int main() {
std::shared_ptr<int> sharedPtr = std::make_shared<int>(70);
std::weak_ptr<int> weakPtr = sharedPtr; // Наблюдатель
if (auto lockedPtr = weakPtr.lock()) { // Проверка, что объект всё ещё существует
std::cout << "Значение через weak_ptr: " << *lockedPtr << std::endl;
} else {
std::cout << "Объект уже удалён." << std::endl;
}
return 0;
}

Указатели и работа с памятью — это важные концепции в C++, которые позволяют более гибко управлять ресурсами и оптимизировать производительность.

Однако неправильное использование указателей может привести к утечкам памяти и другим проблемам.

Умные указатели, введенные в C++11, упрощают управление памятью и помогают избежать распространённых ошибок.

Автор: Дуплей Максим Игоревич

Дата: 07.09.2024

Версия 1.0

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.