#define STRFREE(point) \
do \
{ \
if((point)) \
{ \
if( !in_hash_table( (point) ) ) \
{ \
log_printf( "&RSTRFREE called on str_dup pointer: %s, line %d\n", __FILE__, __LINE__ ); \
log_string( "Attempting to correct." ); \
free( (void*) (point) ); \
} \
else if( str_free((point)) == -1 ) \
log_printf( "&RSTRFREEing bad pointer: %s, line %d\n", __FILE__, __LINE__ ); \
(point) = NULL; \
} \
else \
(point) = NULL; \
} while(0)
class AccountChar
{
private:
AccountChar( const AccountChar & );
AccountChar &operator = ( const AccountChar & );
public:
AccountChar( );
virtual ~AccountChar( );
public:
Account *account;
const char *password;
const char *name;
const char *race;
const char *quitLocation;
const char *clan;
int topLevel;
};
extern std::list< Account * > AccountList;
class Account
{
private:
Account( const Account & );
Account &operator = ( const Account & );
public:
Account( );
virtual ~Account( );
public:
std::list< AccountChar * > CharList;
AccountChar *pending;
const char *host;
const char *name;
const char *lastPlayed;
const char *password;
time_t timer;
bool immortal;
bool multiplay;
int alts;
int accountTopLevel;
};
std::list< Account * > AccountList;
Account::Account( ) :
pending(NULL), host(NULL), name(NULL), lastPlayed(NULL), password(NULL),
timer(0), immortal(0), multiplay(0), alts(0), accountTopLevel(0)
{
}
AccountChar::AccountChar( ) :
account(NULL), password(NULL), name(NULL), race(NULL),
quitLocation(NULL), clan(NULL), topLevel(0)
{
}
$ cat test.cpp
#include <iostream>
using namespace std;
class C1 {
public:
virtual ~C1() { cout << "~C1"; }
};
class C2 : public C1 {
public:
virtual ~C2() { cout << "~C2"; }
};
int main() {
C2* o = new C2();
cout << "deleting o…" << endl;
delete o;
}
$ g++ test.cpp
$ ./a.out
deleting o…
~C2~C1$
for( iAch = CharList.begin( ); iAch != CharList.end( ); ++iAch )
{
ach = *iAch;
CharList.remove( ach ); // <— HERE
deleteptr( ach );
}
for (std::list<AccountChar*>::iterator iter(CharList.begin()), end(CharList.end()); iter != end; ++iter)
{
deleteptr(*iter);
}
CharList.clear();
53 STRFREE( race );
(gdb) print race
No symbol "race" in current context.
(gdb) frame 0
#0 0x000000000045d8e7 in ~Account (this=0xb144e0) at account.cpp:53
53 STRFREE( race );
(gdb) print race
No symbol "race" in current context.
(gdb) print this
$1 = (Account * const) 0xb144e0
(gdb) print this->name
$2 = 0x0
(gdb) print this->race
There is no member or method named race.
(gdb) bt
#0 0x000000000045d8e7 in ~Account (this=0xb144e0) at account.cpp:53
#1 0x000000000053305f in deleteptr<Account> (ptr=@0xb13068) at templates.h:68
#2 0x0000000000524d83 in free_desc (d=0xb13040) at comm.cpp:1090
#3 0x0000000000525894 in close_socket (dclose=0xb13040, force=false) at comm.cpp:1252
#4 0x000000000052ddce in nanny_account_menu (d=0xb13040, argument=0x7fff341b84a0 "0") at comm.cpp:2140
#5 0x0000000000530151 in nanny (d=0xb13040, argument=0x7fff341b84a0 "0") at comm.cpp:4540
#6 0x0000000000531828 in game_loop () at comm.cpp:775
#7 0x0000000000532f63 in main (argc=5, argv=0x7fff341b89d8) at comm.cpp:446
(gdb) frame 0
#0 0x000000000045d8e7 in ~Account (this=0xb144e0) at account.cpp:53
53 STRFREE( race );
(gdb) list
48
49 AccountChar::~AccountChar( )
50 {
51 STRFREE( password );
52 STRFREE( name );
53 STRFREE( race );
54 STRFREE( quitLocation );
55 STRFREE( clan );
56 }
57
(gdb)
Astute readers will probably notice the same thing I did. That's not even the destructor for the account class. So.. Why is GDB saying it is?
Here are the two destructors:
And the deleteptr template:
I'm at a loss, and with GDB behaving like this, I'm not sure how to proceed, or even whether it's being reliable. If any further code is needed to help me figure this out just say so, and I'll toss it in here… I'm tired of ripping my hair out trying to figure this out. =/