Не удаляется указатель - PullRequest
1 голос
/ 22 марта 2019

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

Ниже приведен мой код C ++ для проверки моего понимания.

#include <iostream>
using namespace std;

int main() {

    // Variable to be pointed to by a pointer
    cout << "Create a double variable" << endl;
    double n = 3.1415926;
    cout << "n = " << n << endl;
    cout << "&n = " << &n << endl << endl;

    // Dynamic memory allocation
    cout << "Dynamically allocate memory to a pointer" << endl;
    double * ptr = new double;
    ptr = &n;       // Error when delete ptr
    // *ptr = n;    // Can delete ptr
    cout << "ptr = " << ptr << endl;
    cout << "*ptr = " << *ptr << endl << endl;


    // Free the pointer memory
    cout << "Delete the pointer" << endl;
    delete ptr;
    cout << "Done" << endl;

    return 0;
}

Когда указатель ptr указывает на адрес n (т.е. ptr = &n). Распечатка консоли выглядит следующим образом с ошибкой.

$ ./test
Create a double variable
n = 3.14159
&n = 0x7ffee304f830

Dynamically allocate memory to a pointer
ptr = 0x7ffee304f830
*ptr = 3.14159

Delete the pointer
test(2436,0x118bf05c0) malloc: *** error for object 0x7ffee304f830: pointer being freed was not allocated
test(2436,0x118bf05c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

Но когда указатель назначен так: *ptr = n. Такой ошибки не возникает. Кроме того, ptr указывает на адрес 0x7faa7e400630, который не является адресом n

Насколько я понимаю, ptr в обоих случаях является действительным указателем (с действительным адресом). Но я не знаю, почему delete ptr не работает для случая ptr = &n. Любая помощь для облегчения моего понимания приветствуется. Спасибо

Ответы [ 2 ]

2 голосов
/ 22 марта 2019

Но когда указатель назначен так: *ptr = n.Такой ошибки не возникает.

При выполнении *ptr = n указатель не удаляется.Это простая операция присваивания.ptr указывает на действительную память.Следовательно, присвоение *ptr не является проблемой.

Но я не знаю, почему удаление ptr не работает в случае ptr = &n

Youможет только delete, что было получено new.&n не является одним из таких указателей.Выполнение delete ptr аналогично выполнению delete &n.Это не правильно и является причиной неопределенного поведения.

1 голос
/ 22 марта 2019

Но я не знаю, почему удаление ptr не работает в случае ptr = &n

n - это автоматическая переменная.Удаление адреса автоматической переменной имеет неопределенное поведение.

delete выражение для любого указателя, кроме того, который был возвращен (без размещения) new выражение имеет неопределенное поведение (кроме нулевого указателя; онобезопасно удалить ноль).Так указан язык.Когда поведение не определено, программа может выдать ошибку.

ptr = &n присваивает значение, которое было возвращено new.Так как значение больше нигде не хранится, оно будет невозможно delete.Это называется утечкой памяти.

Но когда указатель назначается так: *ptr = n.Такой ошибки не возникает.

* - оператор косвенного обращения.Это выражение не назначает указатель.ptr по-прежнему указывает на объект в динамическом хранилище.Это не указывает на n.delete выражение по указателю было , возвращаемое новым выражением, имеет четко определенное поведение.Поведение состоит в том, чтобы уничтожить объект и освободить память.

Это назначение устанавливает значение объекта, на которое указывает ptr.Значение этого числа теперь совпадает со значением переменной n.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...