Подводные камни и время жизни
Избегайте висячих представлений
«Подводные камни и время жизни» — бесплатный урок C++ Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Представления не владеют данными
string_view только указывает на символы, которыми владеет другой объект. Если это хранилище исчезает, представление становится висячим, а обращение к нему приводит к неопределённому поведению.
Висячее представление временного объекта
Связывать представление с временным объектом std::string опасно: временный объект уничтожается в конце выражения, и представление начинает указывать на освобождённую память.
#include <string>
#include <string_view>
std::string make() { return "temp"; }
int main() {
std::string_view sv = make(); // dangles immediately
// using sv here is undefined behavior
(void)sv;
}Возврат представления локального объекта
Никогда не возвращайте представление, указывающее внутрь локальной строки: локальный объект уничтожается при возврате из функции.
#include <string>
#include <string_view>
std::string_view bad() {
std::string local = "oops";
return local; // local dies, view dangles
}
int main() { (void)bad(); }Безопасный вариант: представление существующей строки
Представление безопасно, пока его источник существует дольше него. В этом примере строка живёт на протяжении всей функции.
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string s = "alive";
std::string_view sv = s;
std::cout << sv << "\n"; // safe
}Без завершающего нулевого символа
Данные представления не обязаны заканчиваться символом \0. Передача sv.data() функции C, ожидающей C-строку, может привести к чтению за пределами представления.
Используйте длину, а не strlen
Всегда используйте sv.size() для получения длины вместо функций для C-строк, поскольку представление может быть срезом большего буфера.
#include <iostream>
#include <string_view>
int main() {
std::string_view sv = std::string_view("hello world").substr(0, 5);
std::cout << sv.size() << "\n"; // 5, not 11
}Изменение источника
Если исходная строка перераспределяется, например из-за увеличения ёмкости при вызове push_back, существующие представления внутри неё становятся недействительными.
Хранение представлений в полях
Будьте осторожны, сохраняя string_view в качестве поля класса: необходимо гарантировать, что данные, на которые оно ссылается, существуют дольше объекта. Если сомневаетесь, храните вместо него std::string.
Параметры обычно безопасны
Использование string_view как параметра функции — безопасный и идиоматичный вариант: аргумент существует дольше вызова.
#include <iostream>
#include <string_view>
size_t len(std::string_view sv) { return sv.size(); }
int main() {
std::cout << len("temporary is fine here") << "\n";
}Копируйте, когда нужно сохранить данные
Если нужно сохранить текст дольше времени жизни его источника, скопируйте его в std::string. Копирование — это плата за владение данными.
#include <string>
#include <string_view>
std::string keep(std::string_view sv) {
return std::string(sv); // owns a copy
}
int main() { (void)keep("persist"); }Практическое правило
Предпочитайте string_view для параметров и локальных объектов с коротким временем жизни. Избегайте его в качестве возвращаемого типа или долгоживущего поля, если только данные явно не живут дольше.
Быстрая проверка
Проверьте своё понимание времени жизни представлений.
Повторение
Вы узнали о проблемах и времени жизни представлений:
- Представления не владеют данными; источник должен существовать дольше представления.
- Избегайте представлений временных и локальных объектов.
- Представления не обязаны завершаться нулевым символом, используйте
size(). - Копируйте данные в
std::string, когда нужно сохранить текст.
Часто задаваемые вопросы
Урок «Подводные камни и время жизни» бесплатный?
Да — полный текст урока «Подводные камни и время жизни» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Подводные камни и время жизни»?
Избегайте висячих представлений Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Подводные камни и время жизни»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужен string_view
- Создание представлений
- Подводные камни и время жизни
- Алгоритмы обработки строк