Я слышал, что в стеке есть только указатели на данные
Вы ошиблись.Стек содержит фактические данные.Однако, если эти данные являются указателем, то это то, что хранится.
И если да, то где хранятся данные?Например, char * a = "bbbb";a - помещается в стек, "bbbb" - где-то еще.Где?
Да, a
(указатель) хранится в стеке.Фактическая строка "bbbb"
хранится в фиксированной части исполняемого файла.
Правильный ли приведенный выше код означает утечку памяти в размере 1000000 байт?Переменная ar уничтожена, но данные, на которые она указала, все еще существуют.И мы не можем использовать здесь удаление, так как ar не выделяется динамически.
Нет, существует разница между массивами и указателями на массивы.ar
(все 1000000 байт) будет храниться в стеке.Это отличается от char const* ar = "... 1000000 chars ...";
.Поскольку ar
находится в стеке, оно будет автоматически "освобождено".
char const* a = "abcde"; // a is on the stack, pointing to "abcde" somewhere else.
char const b[6] = "abcde"; // *all* of b is on the stack, all 6 bytes
Проблема в вашем коде состоит в том, что pi
указывает на что-то в стеке, которого больше нет.Это может произойти, когда вы запускаете код, потому что «освобождение» данных в стеке ничего не делает с данными в не отладочных сборках.Это не утечка памяти, у вас просто недопустимый указатель.
Последнее замечание: хотя практически все современные компьютерные архитектуры используют стек вызовов, стандарт C ++ не упоминает об этом.Обратите внимание, что люди часто говорят, что переменная «в стеке», но на самом деле она может просто существовать в регистре.Например, если вы скомпилировали свой код, переменная pi
, вероятно, никогда не будет касаться стека, скорее всего, она просто останется в регистре на время действия функции, потому что обращение к стеку относительно дорого (по сравнению с регистрами).