c ++ удалить объект за пределами области создания с указателем? - PullRequest
0 голосов
/ 12 июня 2018

Я делаю некоторые обучающие упражнения на с ++ и столкнулся с интересным вопросом.Возьмите этот пример программы.

#include <string>
#include <iostream>

char* pointer1;

void temp() {

    char* s1 = new char;
    *s1 = 'z';
    pointer1 = s1;
    std::cout << *pointer1 << std::endl;
    for (int i = 0; i < 90000; i++) {
        // Waste some processor time.
    }
}

int main() {

    temp();
    std::cout << *pointer1 << std::endl;
    delete pointer1;
    //delete &pointer1;
    std::cout << *pointer1 << std::endl;
    return 0;

}

Когда вы запустите его, он напечатает 'z' дважды, затем какой-нибудь случайный мусор.Что я и ожидал.Если вы удалите комментарий «delete & pointer1» и закомментируете первое удаление и запустите программу, вы получите ошибку неверного указателя из вывода.Я предполагаю, что это удаление адреса, а то, что на самом деле там хранится, остается.

Мой вопрос: при вызове 'delete pointer1' он удаляет 'char * s1' или просто адрес, где находится s1хранится?При вызове «delete & pointer1» адрес удаляется, но s1 все еще находится в памяти?

1 Ответ

0 голосов
/ 12 июня 2018

Адрес, на который указывает pointer1, был выделен new.Следовательно, правильно, даже необходимо, вызывать delete по этому адресу.

Однако, &pointer1 дает вам адрес, где хранится сам pointer1.И этот блок памяти не был выделен new.Следовательно, категорически запрещается вызывать delete, что именно и говорит вам об ошибке.

Итак, да, delete pointer1 освобождает память, выделенную new ранее.Но нет, delete &pointer1 не делает ничего, кроме того, что является незаконным.

Кроме того, доступ к памяти, которую вы называли delete ранее, является неопределенным поведением.Итак, ваш второй *pointer1 - это тоже ничего, что вы хотите написать в программе, которую вы не хотите аварийно завершить, или, что еще хуже, которая дает вам непредсказуемые результаты.

...