Article View: borland.public.cppbuilder.nativeapi
Article #10506problem with STL containers
From: zero
Date: Tue, 13 Apr 2004 12:54
Date: Tue, 13 Apr 2004 12:54
467 lines
15221 bytes
15221 bytes
First a short discription of my program. I have a bot that connects to an
internet chess server. Whenever the bot logs on, it loads certain
information from file, and puts it in STL containers (specifically sets &
maps). When disconnecting for any reason, the containers are converted to
strings, and saved to disk, so they can be loaded again when the bot logs
back on. Periodically (triggered by a timer event), the bot mails a log to
addresses contained in two of the maps. The same timer is used to send the
output buffer to the server (such a buffer is needed because if you send
too much data at once, the server closes the connection as a security
precaution). There is also a mechanism that automatically re-connects the
bot if it is disconnected.
Now the problem. If the bot disconnects a few times, the log gets mailed
normally the first time, but the next time it should be sent, all the
containters are empty! This of course means the log can't be sent, 'cause
it gets the mail addresses from two of the containers. I have no idea how
or why this happens.
I'd appreciate any ideas on how to fix this.
Here are some parts of the code:
typedef std::map<AnsiString, int, myless> guideMap;
typedef std::map<AnsiString, AnsiString, myless> adrMap;
typedef std::set<AnsiString> headSet;
class GuideBot :public CNBot
{
private:
int assistsAsked;
int unansweredAssists;
int guestAssists;
guideMap theGuides;
guideMap theAdmins;
headSet theTDHeads;
adrMap theAAdr;
adrMap theGAdr;
void handleLevel1Block();
void processTell(AnsiString tellFrom, AnsiString theTell, UINT type);
void findGAlias(AnsiString tellFrom, AnsiString theTell);
void findTDAlias(AnsiString tellFrom, AnsiString theTell);
void findAAlias(AnsiString tellFrom, AnsiString theTell);
void loadAll();
bool isHead(AnsiString user);
bool isGHead(AnsiString user);
bool isAHead(AnsiString user);
bool isTDHead(AnsiString user);
public:
GuideBot():CNBot() {}
GuideBot(AnsiString asHandle, AnsiString asPassword):CNBot(asHandle,
asPassword) {}
GuideBot(AnsiString asFileName, TClientSocket *tcsConnection):CNBot
(asFileName, tcsConnection) {}
GuideBot(AnsiString asFileName, TClientSocket *tcsConnection, AnsiString
asSection):CNBot(asFileName, tcsConnection, asSection) {}
~GuideBot() {}
void onConnect(TCustomWinSocket *Socket);
void saveAll();
void mailDump();
int countingSince;
};
void __fastcall TForm1::ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Bot->onConnect(Socket);
HandleEdit->Enabled = false;
PasswordEdit->Enabled = false;
CommandEdit->Enabled = true;
if(Application->ShowMainForm)
CommandEdit->SetFocus();
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::ClientSocketDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Output->Lines->Add("**** DISCONNECTED ****");
HandleEdit->Enabled = true;
PasswordEdit->Enabled = true;
CommandEdit->Enabled = false;
Bot->saveAll();
if(Bot->stayConnected)
{
reconnectValue = 4000;
reconnectTimer = 0;
}
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::ClientSocketError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
Bot->saveAll();
ErrorCode = 0;
ClientSocket->Close();
reconnectValue = 4000;
reconnectTimer = 0;
TrayMessage(NIM_MODIFY);
}
void __fastcall TForm1::SendTimer(TObject *Sender)
{
reconnectTimer++;
if(reconnectTimer == reconnectValue)
{
reconnectValue = -1;
Connect1Click(Sender);
}
myCounter++;
if(Bot != NULL)
{
Bot->sendoBuffer(ClientSocket->Socket);
}
if(myCounter%120000 == 0) // every hour
{
Bot->saveAll();
Output->Clear();
}
// if(myCounter == 20160000) // every 7 days
if(myCounter == 2000)
{
Bot->mailDump();
myCounter = 0;
Bot->countingSince = myCounter;
Bot->saveAll();
}
}
void GuideBot::onConnect(TCustomWinSocket *Socket)
{
stayConnected = true;
AnsiString command;
command = setDGLevel();
Socket->SendText(command + char(10));
Socket->SendText(getHandle() + char(10));
Socket->SendText(getPassword() + char(10));
if(theGuides.begin() == theGuides.end())
int lalala = 0;
loadAll();
if(theGuides.begin() == theGuides.end())
int lalala = 0;
countingSince = Form1->myCounter;
}
void GuideBot::loadAll()
{
int iPos, answered;
AnsiString theLine, guideName;
TStringList *strList = new TStringList; // declare the list
try // use the list in a try block
{
strList->LoadFromFile("guides.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings[i];
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
answered = theLine.SubString(1, theLine.Length()).ToInt();
theGuides.insert(guideMap::value_type(guideName, answered));
}
strList->LoadFromFile("admins.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings[i];
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
answered = theLine.SubString(1, theLine.Length()).ToInt();
theAdmins.insert(guideMap::value_type(guideName, answered));
}
strList->LoadFromFile("gheads.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings[i];
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
theGAdr.insert(adrMap::value_type(guideName, theLine));
}
strList->LoadFromFile("aheads.ini");
for(int i = 0; i < strList->Count; i++)
{
theLine = strList->Strings[i];
iPos = theLine.Pos("\'");
guideName = theLine.SubString(1, iPos-1);
theLine = theLine.SubString(iPos+1, theLine.Length()-iPos+1);
theAAdr.insert(adrMap::value_type(guideName, theLine));
}
strList->LoadFromFile("tdheads.ini");
for(int i = 0; i < strList->Count; i++)
theTDHeads.insert(strList->Strings[i]);
}
__finally
{
delete strList; // destroy the list object
}
TIniFile *times;
times = new TIniFile(ExtractFilePath(Application->ExeName)+"times.ini");
assistsAsked = times->ReadInteger("assists", "assistsAsked", 0);
guestAssists = times->ReadInteger("assists", "guestAssists", 0);
unansweredAssists = times->ReadInteger("assists", "unansweredAssists",
0);
delete times;
}
void GuideBot::saveAll()
{
AnsiString aLine;
int sec = 60*(Form1->myCounter - countingSince)/2000;
int min = 0;
int hour = 0;
int day = 0;
while(sec >= 60)
{
min = sec/60;
sec -= min*60;
}
while(min >= 60)
{
hour = min/60;
min -= hour*60;
}
while(hour >= 24)
{
day = hour/24;
hour -= day*24;
}
TIniFile *times;
times = new TIniFile(ExtractFilePath(Application->ExeName)+"times.ini");
times->WriteInteger("guides", "sec", sec);
times->WriteInteger("guides", "min", min);
times->WriteInteger("guides", "hour", hour);
times->WriteInteger("guides", "day", day);
times->WriteInteger("assists", "assistsAsked", assistsAsked);
times->WriteInteger("assists", "guestAssists", guestAssists);
times->WriteInteger("assists", "unansweredAssists", unansweredAssists);
delete times;
times = new TIniFile(ExtractFilePath(Application->ExeName)
+"settings.ini");
times->WriteInteger("Program", "myCounter", Form1->myCounter);
delete times;
TStringList *strList = new TStringList; // declare the list
try // use the list in a try block
{
guideMap::iterator itr;
for(itr = theGuides.begin(); itr != theGuides.end(); itr++)
{
aLine.sprintf("%s'%i", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("guides.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
guideMap::iterator itr;
for(itr = theAdmins.begin(); itr != theAdmins.end(); itr++)
{
aLine.sprintf("%s'%i", (*itr).first, (*itr).second);
strList->Add(aLine);
}
strList->SaveToFile("admins.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
adrMap::iterator itr;
for(itr = theGAdr.begin(); itr != theGAdr.end(); itr++)
{
aLine.sprintf("%s'%s", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("gheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
adrMap::iterator itr;
for(itr = theAAdr.begin(); itr != theAAdr.end(); itr++)
{
aLine.sprintf("%s'%s", (*itr).first, (*itr).second);
strList->Add(aLine);
}
// if(strList->Count > 0)
strList->SaveToFile("aheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
strList = new TStringList;
try // use the list in a try block
{
headSet::iterator itr;
for(itr = theTDHeads.begin(); itr != theTDHeads.end(); itr++)
strList->Add(*itr);
// if(strList->Count > 0)
strList->SaveToFile("tdheads.ini");
}
__finally
{
delete strList; // destroy the list object
}
}
void GuideBot::mailDump()
{
if(theGuides.begin() == theGuides.end())
{
loadAll();
return;
}
TIniFile *times;
int total = 0;
int guides = 0;
int sec;
AnsiString ending1, ending2, aLine;
guideMap::iterator itr1;
adrMap::iterator itr2;
TStringList *strList;
Form1->MailSender->PostMessageA->Body->Clear();
Form1->MailSender->PostMessageA->ToAddress->Clear();
sec = 60*(Form1->myCounter - countingSince)/2000;
int min = 0;
int hour = 0;
int day = 0;
times = new TIniFile(ExtractFilePath(Application->ExeName)+"times.ini");
sec += times->ReadInteger("guides", "sec", 0);
min += times->ReadInteger("guides", "min", 0);
hour += times->ReadInteger("guides", "hour", 0);
day += times->ReadInteger("guides", "day", 0);
delete times;
while(sec >= 60)
{
min = sec/60;
sec -= min*60;
}
while(min >= 60)
{
hour = min/60;
min -= hour*60;
}
while(hour >= 24)
{
day = hour/24;
hour -= day*24;
}
ending1.sprintf("Counting since %i days, %i hours, %i minutes and %i
seconds.", day, hour, min, sec);
ending2.sprintf("%i assists were asked, of which %i (%2.1f%%) were guest
assists. %i assists were left unanswered (%2.1f%%)", assistsAsked,
guestAssists, ((assistsAsked == 0) ? 0.0 : ((float)guestAssists/(float)
assistsAsked)*100), unansweredAssists, ((assistsAsked == 0) ? 0.0 :
((float)unansweredAssists/(float)assistsAsked)*100));
strList = new TStringList();
try
{
for(itr1 = theGuides.begin(); itr1 != theGuides.end(); itr1++)
{
aLine.sprintf("%s answered %i assists", (*itr1).first,
(*itr1).second);
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
guides++;
total += (*itr1).second;
}
aLine.sprintf("%i Guides answered %i assists (%2.1f%% of answered
assists)", guides, total, ((assistsAsked-unansweredAssists == 0) ? 0.0 :
((float)total/(float)(assistsAsked-unansweredAssists))*100));
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
Form1->MailSender->PostMessageA->Body->Add(ending1);
strList->Add(ending1);
Form1->MailSender->PostMessageA->Body->Add(ending2);
strList->Add(ending2);
Form1->MailSender->PostMessageA->Subject = "Guide assist stats";
for(itr2 = theGAdr.begin(); itr2 != theGAdr.end(); itr2++)
Form1->MailSender->PostMessageA->ToAddress->Add((*itr2).second);
Form1->MailSender->Connect();
Form1->MailSender->SendMail();
Form1->MailSender->Disconnect();
Form1->MailSender->PostMessageA->Body->Clear();
Form1->MailSender->PostMessageA->ToAddress->Clear();
guides = 0;
total = 0;
for(itr1 = theAdmins.begin(); itr1 != theAdmins.end(); itr1++)
{
aLine.sprintf("%s answered %i assists", (*itr1).first,
(*itr1).second);
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
guides++;
total += (*itr1).second;
}
aLine.sprintf("%i Admins answered %i assists (%2.1f%% of answered
assists)", guides, total, ((assistsAsked-unansweredAssists == 0) ? 0.0 :
((float)total/(float)(assistsAsked-unansweredAssists))*100));
Form1->MailSender->PostMessageA->Body->Add(aLine);
strList->Add(aLine);
Form1->MailSender->PostMessageA->Body->Add(ending1);
strList->Add(ending1);
Form1->MailSender->PostMessageA->Body->Add(ending2);
strList->Add(ending2);
Form1->MailSender->PostMessageA->Subject = "Admin assist stats";
for(itr2 = theAAdr.begin(); itr2 != theAAdr.end(); itr2++)
Form1->MailSender->PostMessageA->ToAddress->Add((*itr2).second);
Form1->MailSender->Connect();
Form1->MailSender->SendMail();
Form1->MailSender->Disconnect();
strList->SaveToFile("dump.txt");
}
__finally
{
delete strList;
}
guideMap::iterator itr;
for(itr = theGuides.begin(); itr != theGuides.end(); itr++)
(*itr).second = 0;
theAdmins.clear();
assistsAsked = 0;
guestAssists = 0;
unansweredAssists = 0;
}
Technical Details
Message-ID:
<Xns94CA9752D647Azerothishi@195.130.132.68>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!news.glorb.com!ecngs!feeder.ecngs.de!feed1.news.be.easynet.net!ossa.telenet-ops.be!hebe.telenet-ops.be.POSTED!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 10cc67,d8f4075e4715e80c,start X-Google-Attributes: gid10cc67,public X-Google-ArrivalTime: 2004-04-13 05:54:32 PST Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!news.glorb.com!ecngs!feeder.ecngs.de!feed1.news.be.easynet.net!ossa.telenet-ops.be!hebe.telenet-ops.be.POSTED!not-for-mail Newsgroups: borland.public.cppbuilder.nativeapi Subject: problem with STL containers From: zero <zero@this.hi> Organization: Your Company Message-ID: <Xns94CA9752D647Azerothishi@195.130.132.68> User-Agent: Xnews/5.04.25 Lines: 467 Date: Tue, 13 Apr 2004 12:54:31 GMT NNTP-Posting-Host: 213.224.5.250 X-Complaints-To: abuse@telenet.be X-Trace: hebe.telenet-ops.be 1081860871 213.224.5.250 (Tue, 13 Apr 2004 14:54:31 CEST) NNTP-Posting-Date: Tue, 13 Apr 2004 14:54:31 CEST