Problem with auto_ptr !!!
-
Hello to all. I've checked this following article (http://www.cuj.com/experts/1906/hyslop.htm?topic=experts) at CUJ web site and decided to use it in my own application. So here we go. I have managed to implement the factory inside a windows DLL. But i'm having weird problems with it. Mainly the genericFactory::create method. This is how i've implemented it (with the modification that I use a pointer to a function with three std::string parameters) : template std::auto_ptr genericFactory::create(const classIDKey &className, const std::string& p1, const std::string& p2, const std::string& p3) const { std::auto_ptr ret(0); FN_REGISTRY::const_iterator regEntry=registry.find(className); if (regEntry != registry.end()) { ret = regEntry->second(p1, p2, p3); } return ret; } And in my client code this is how I call it : std::auto_ptr tbl(0); tbl = genericFactory::instance().create("HistoricalDataTbl", host, user, pwd); ----------------------------------------------------------------------------------------------- When I trace inside the create method, the "ret" variable is fine and points to a valid MySQLTable object. BUT, when the function returns to the client code... I get an unhandled exception error. This error is generated inside the auto_ptr<>::reset() method. To be more precise, the "tbl" auto_ptr in the client code is supposed to be initialized with a NULL pointer but when getting back from genericFactory::create method the "tbl" pointer points to an invalid MySQLTable object. The quilty code inside auto_ptr : void reset(_Tp* __px=0) { _Tp* __pt = this->get(); if (__px != __pt) delete __pt; //offending line... this->__set(__px); } So i'm currently puzzled has to why the "tbl" variable points to a bad MySQLTable object!?!?!?! Any help would be greatly appreciated :-D Luc.
-
Hello to all. I've checked this following article (http://www.cuj.com/experts/1906/hyslop.htm?topic=experts) at CUJ web site and decided to use it in my own application. So here we go. I have managed to implement the factory inside a windows DLL. But i'm having weird problems with it. Mainly the genericFactory::create method. This is how i've implemented it (with the modification that I use a pointer to a function with three std::string parameters) : template std::auto_ptr genericFactory::create(const classIDKey &className, const std::string& p1, const std::string& p2, const std::string& p3) const { std::auto_ptr ret(0); FN_REGISTRY::const_iterator regEntry=registry.find(className); if (regEntry != registry.end()) { ret = regEntry->second(p1, p2, p3); } return ret; } And in my client code this is how I call it : std::auto_ptr tbl(0); tbl = genericFactory::instance().create("HistoricalDataTbl", host, user, pwd); ----------------------------------------------------------------------------------------------- When I trace inside the create method, the "ret" variable is fine and points to a valid MySQLTable object. BUT, when the function returns to the client code... I get an unhandled exception error. This error is generated inside the auto_ptr<>::reset() method. To be more precise, the "tbl" auto_ptr in the client code is supposed to be initialized with a NULL pointer but when getting back from genericFactory::create method the "tbl" pointer points to an invalid MySQLTable object. The quilty code inside auto_ptr : void reset(_Tp* __px=0) { _Tp* __pt = this->get(); if (__px != __pt) delete __pt; //offending line... this->__set(__px); } So i'm currently puzzled has to why the "tbl" variable points to a bad MySQLTable object!?!?!?! Any help would be greatly appreciated :-D Luc.
Well, your sample code doesn't look good since the template parameters were lost by the HTML translation. Try putting the code inside pre tags next time. However, I did take a quick peek it and it seems like the problem is with your
regEntry
variable. It's a local variable which, I assume, is returning to you a pointer to aMySQLTable
object via thesecond
function which it created internally. My guess is that when the create function returns,regEntry
goes away and so does theMySQLTable
pointer that it was holding -- which is also in yourret
variable. Soret
is left holding on to a pointer which is no longer valid. That's one guess, based on my complete lack of knowledge on FN_REGISTRY. Another guess is that it has to do with howret
variable is being copied and freed when it gets returned. But it shouldn't be that sinceret
would be "released" before being copied totbl
, and then it would be freed with a NULL pointer -- should be no problem. BTW, I noticed you're not using Microsoft's auto_ptr implementation, which doesn't even have a reset (at least not the one in VC6.0) Regards, Alvaro
Well done is better than well said. -- Benjamin Franklin (I actually prefer medium-well.)
-
Well, your sample code doesn't look good since the template parameters were lost by the HTML translation. Try putting the code inside pre tags next time. However, I did take a quick peek it and it seems like the problem is with your
regEntry
variable. It's a local variable which, I assume, is returning to you a pointer to aMySQLTable
object via thesecond
function which it created internally. My guess is that when the create function returns,regEntry
goes away and so does theMySQLTable
pointer that it was holding -- which is also in yourret
variable. Soret
is left holding on to a pointer which is no longer valid. That's one guess, based on my complete lack of knowledge on FN_REGISTRY. Another guess is that it has to do with howret
variable is being copied and freed when it gets returned. But it shouldn't be that sinceret
would be "released" before being copied totbl
, and then it would be freed with a NULL pointer -- should be no problem. BTW, I noticed you're not using Microsoft's auto_ptr implementation, which doesn't even have a reset (at least not the one in VC6.0) Regards, Alvaro
Well done is better than well said. -- Benjamin Franklin (I actually prefer medium-well.)
Here is how FN_REGISTRY is defined...
typedef std::auto_ptr (*BASE_CREATE_FN)(const std::string&,
const std::string&,
const std::string&);// FN_REGISTRY is the registry of all the BASE_CREATE_FN
// pointers registered. Functions are registered using the
// regCreateFn member function (see below).
typedef std::map FN_REGISTRY;
FN_REGISTRY registry;And I use STLPort !!! P.S. How come, after using the pre tags, that my "<" and ">" gets deleted !?!?!?