[БЕЗ_ЗВУКА] Давайте подведем итоги всего раздела. В этом разделе мы с вами познакомились с моделью памяти в языке C++. Мы узнали, что есть две области памяти, в которых хранятся объекты, с которыми работают программы на C++. Это стек и куча. Давайте еще раз их сравним. Во-первых, скажем, что чтобы создать объект на стеке, нужно просто объявить локальную переменную. Чтобы создать объект в куче, нужно воспользоваться оператором new, который выделит необходимую память, вызовет конструктор для объекта и вернет указатель на эту память. Принципиальным отличием стека и кучи является то, что объекты, созданные на стеке, разрушаются автоматически. Как только переменная выходит из области видимости, то для нее вызывается деструктор и соответствующий объект разрушается. Чтобы разрушить объект, созданный в куче, нужно вызвать оператор delete, который вызовет деструктор и освободит раннее выделенную память. Стек и куча отличаются своими областями применения. На стеке размещаются локальные переменные функций, то есть те объекты, которые живут не дольше, чем живет сама функция. Если же нам нужно создать объект, который должен жить дольше, чем функция, которая его создала, мы не можем пользоваться стеком, и поэтому мы создаем этот объект в куче. Кроме того, в этом разделе мы познакомились с указателями, с их арифметикой, с тем, как их применять, и, собственно, детально изучили операторы new и delete. И мы посмотрели, что использование new и delete в программах обладает рядом недостатком. Во-первых, если мы создали какой-то объект с помощью new, то мы можем забыть его удалить с помощью оператора delete. И в результате мы получим утечку памяти. Мы достаточно красноречиво продемонстрировали, к каким проблемам приводят утечки памяти. Причем даже возможны ситуации, когда мы не забыли вызвать delete, но это все равно не помогло. Такой пример как раз приведен у нас на экране — он, конечно, такой немножечко модельный, но демонстрирует проблему. Мы создали на куче объект типа string, как-то с ним потом поработали и вызвали оператор delete. Все нормально. Но, возможно, со временем мы вдруг поняли, что нам не надо ничего делать, если объект, если строчка t — входной параметр — оказался пустым. И мы вставили в какое-то место нашей функции return, если строчка оказалась пустой. Соответственно, в этом случае у нас возникает утечка памяти. И это серьезная проблема, которая возникает при использовании new и delete. Другая проблема заключается в том, что мы можем не перепутать delete и delete с квадратными скобками. Мы это демонстрировали в наших примерах, когда мы заменяли один delete на другой и наша программа переставала работать. И допустить эту ошибку, на самом деле, достаточно просто, потому что компилятор никак не помогает нам, не подсказывает и не говорит, что мы в простой delete, например, передаем указатель, созданный с помощью new с квадратными скобками. Я это все рассказываю вам, для того чтобы подчеркнуть главную мысль всего нашего раздела про модель памяти. Все, что связано с операторами new и delete, с арифметикой указателей, мы вам рассказали только для того, чтобы потом рассказать внутреннее устройство контейнеров языка C++, чтобы вы понимали, как они устроены под капотом и как именно функционируют. В современном языке C++ нет ни одной веской причины применять new и delete в прикладном коде. То есть если вы пишете какую-то программу, которая решает какую-то конкретную задачу — это и есть прикладной код, — то в нем нет смысла применять new и delete. Вместо них есть более удобные и более безопасные альтернативы. Самый простой пример — это, собственно, вектор. Если вам нужно в куче создать n объектов, создайте вектор. Не нужно вызывать new с квадратными скобками. Если же вы разрабатываете библиотеку — вот как, например, мы разрабатывали свой вектор, — то да, там, конечно, без new и delete не обойтись. Но это касается библиотек — это более сложно, а в прикладном коде нет — еще раз скажу — ни одной причины применять new и delete.