2015-01-05 2 views
3
#include<iostream> 

class base{ 
    public: 
    base(){}; 
    base (base& b) {}; 
    virtual void run(){}; 
    ~base(){std::cout<<"destructor for base"<<std::endl;}; 
}; 

class derived : public base { 
    int alpha; 
    public: 
    derived (): alpha (0), base() {}; 
    derived (base& b) : alpha(0), base(b) {}; 
    void run(){}; 
    int* get_address() { return &(this->alpha); }; 
    ~derived(){std::cout<<"destructor for derived"<<std::endl;}; 
}; 

void make_derived (std::shared_ptr<base>& b){ 
    b.reset (new derived()); 
} 

int main(){ 
    std::shared_ptr<base> b; 
    make_derived (b) ; 
    std::shared_ptr<derived> d = std::dynamic_pointer_cast<derived> (b); 

    std::shared_ptr<int> a (d->get_address()); 

    b->run(); 
} 

Я скомпилировал этот код и запустил его. Сообщение об ошибке «освобождение указателя не было». Это довольно распространенное сообщение об ошибке. Я, однако, не понимаю, почему появляется что-то освобожденное. Он умирает сразу после std::shared_ptr<int> a (d->get_address());. Кто-нибудь знает, как это исправить?C++ указатель, который был освобожден, не был выделен коротким примером

+0

'alpha' был выделен как часть всего объекта' производный'. Объект 'производный' должен быть освобожден, а не его члены. –

+0

@JosephMansfield Хорошо .. тогда я не понимаю, почему 'производный' получает освобожденный – user3089810

+0

Вам не следует создавать объект shared_ptr на основе оператора« address of ». т. е. d-> get_address() недействительно для инициализации shared_ptr (ничего не называемого «new int»). – Charlie

ответ

1

Не delete То, что вы не сделали new. Когда вы передаете указатель на конструктор shared_ptr или reset, вы устанавливаете отложенный вызов на delete на этот указатель (при условии, что вы также не выполняете пользовательский деаэратор). Это то, что происходит здесь:

std::shared_ptr<int> a (d->get_address()); 

Вы передавая адрес в int к shared_ptr конструктора. Но что int не было выделено new, поэтому его не должно обрабатываться shared_ptr.

+0

Итак, простейшим решением было бы просто использовать обычный указатель на C++? – user3089810

+1

Простейшим решением было бы удалить эту строку целиком, так как вы ничего не делаете с этим указателем. –

+0

Хорошо .. Я ничего не делаю только в этом упрощенном примере. Я делаю что-то в своей реальной программе. Использование обычного указателя отлично работает. Большое спасибо за эту помощь. – user3089810

Смежные вопросы