почему ошибка: освобожденный указатель не выделен - PullRequest
0 голосов
/ 07 апреля 2019
#include <iostream>

using namespace std;
int main(int argc, char *argv[]) {
    int* a = new int;
    *a = 5;

    int* b = new int;
    *b = 6;

    int* temp = a;
    delete(a);
    a = b;
    b = temp;

    cout << *temp << endl;
    delete (temp); // error



    return 0;
}

ошибка: malloc: *** ошибка для объекта 0x7ffdff400630: освобожденный указатель не выделен. Но если я не delete(a), это работает.

Ответы [ 2 ]

4 голосов
/ 07 апреля 2019

Когда вы используете

int* temp = a;

и a и temp указывают на одну и ту же память, которая была выделена в строке

int* a = new int;

Когда вы используете

delete(a);

эта память была освобождена. В то время и temp, и a являются висящими указателями.

Используя

a = b;
b = temp;

вы изменили a, чтобы указать на действительную память, но теперь и b, и temp - это висячие указатели.

Использование temp в

cout << *temp << endl;
delete (temp); // error

не правильно. Оба они являются причиной неопределенного поведения. С неопределенным поведением бессмысленно пытаться понять, что происходит - все может случиться.

Но если я не delete(a), это работает.

Это имеет смысл. Без этого вызова все указатели остаются действительными до конца функции.

Вы должны добавить код, чтобы удалить оба указателя до конца функции. Но тогда вы должны отслеживать, какие указатели действительны для использования в вызовах на delete.

Вы можете распечатать их значения, чтобы понять это.

std::cout << "a: " << (void*)a << std::endl;
std::cout << "b: " << (void*)b << std::endl;
std::cout << "temp: " << (void*)temp << std::endl;
1 голос
/ 07 апреля 2019

В

int* temp = a;

Вы делаете копию указателя, поэтому a и temp указывают на одну и ту же вещь, затем в

delete a;

Вы удаляете a такtemp становится висящим указателем, отмена ссылки вызывает неопределенное поведение.

В идеале вы должны сделать

temp = null; 

сразу после delete или для лучшего использования общего указателя, который поставляетсяс современным CPP.

#include <iostream>
#include <memory>

auto main() -> int
{
    auto ptr = std::make_shared<int>(5);

    std::cout << "ptr value is " << *ptr << std::endl;

    auto ptr1 = ptr; // Reference counted copy

    std::cout << "ptr value is " << *ptr1 << std::endl;
    std::cout << "Total reference count :" << ptr1.use_count() << std::endl;
    ptr.reset(); // Resetting  ptr, thus reference count drops to 1
    std::cout << "Total reference count :" << ptr1.use_count() << std::endl;;

    return 0;
}
...