user3089810
user3089810

Reputation: 77

c++ pointer being freed was not allocated with a short example

#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();
}

I compiled this code and ran it. The error message is "pointer being freed was not allocated". This is a pretty common error message. I, however, don't understand why there appears anything freed. It dies immediately after std::shared_ptr<int> a ( d->get_address() );. Anybody knows how to fix this?

Upvotes: 3

Views: 230

Answers (1)

Benjamin Lindley
Benjamin Lindley

Reputation: 103713

Don't delete that which you did not new. When you pass a pointer to a shared_ptr constructor or reset function, you are setting up a deferred call to delete on that pointer (assuming you don't also pass a custom deleter). That's what is happening here:

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

You're passing the address of an int to a shared_ptr constructor. But that int was not allocated with new, and so should not be handled by a shared_ptr.

Upvotes: 1

Related Questions