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
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;
*/