Boost logo

Boost Users :

From: Jean-François Brouillet (verec_at_[hidden])
Date: 2005-05-14 14:13:09


I'm confused again :(

I've read the note about shared_ptr & this in the documentation,
but I'm still a bit lost as to how I'm supposed to overcome the
problem.

The code below would work fine if I were to remove all this smart
pointer business and handle new & delete by hand. But because
this kind of code is just so typical of the huge Java library
I'm porting, there's not much choice but to get an as "surprise
free" object model as possible.

As far as I understand what is going on, the reason why
the runtime is reporting a "double free" is because two independently
constructed shared_ptrs' do not share the same reference count,
which intrusive_ptr would allow me to do, except that intrusive_ptr
doesn't vary "polymorphically" with its body as shared_ptr does.

Obviously, I could "roll my own" solution by modifying shared_ptr
to use a common reference count the way intrusive_ptr does, but
I was wondering: is that my only course of action?

Or has anyone found a workaround/clever use of the boost::xxx_ptr
to overcome this situation?

Many thanks

--
JFB
#include <iostream>
#include <boost/shared_ptr.hpp>
struct TaskDoneStruct {
     virtual void    success() = 0 ;
     virtual void    failure() = 0 ;
} ;
typedef boost::shared_ptr<TaskDoneStruct> TaskDone ;
struct LongTaskStruct {
     TaskDone    callback ;
     virtual void    setCallback(const TaskDone& td) {
         this->callback = td ;
     }
     virtual void run() {
         start() ;
         complete() ;
     }
     virtual void start() = 0 ;
     virtual void complete() {
         if (callback) {
             callback->success() ;
         }
     }
     virtual     ~LongTaskStruct() {}
} ;
struct MyTaskStruct : public LongTaskStruct, TaskDoneStruct {
     MyTaskStruct() {
         setCallback(TaskDone(this)) ;  // this is the root of the
                                        // double free problem
     }
     virtual void start() {
         std::cout << "Starting lengthy process ..." << std::endl ;
     }
     virtual void success() {
         std::cout << "Done lengthy process ..." << std::endl ;
     }
     virtual void failure() {
         std::cout << "Aborted lengthy process ..." << std::endl ;
     }
} ;
typedef boost::shared_ptr<MyTaskStruct> MyTask ;
void
tastTest() {
     MyTask  myTask(new MyTaskStruct) ;
     myTask->run() ;
}
int
main(
     int     argc
,   char *  argv) {
     std::cout << "Tests starting ..." << std::endl ;
     tastTest() ;
     std::cout << "Tests done ..." << std::endl ;
     return 0 ;
}
/*
BoostTests(1270) malloc: ***  Deallocation of a pointer not
malloced: 0x300180; This could be a double free(), or free()
called with the middle of an allocated block;
*/

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net