PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Stackoverflow im Destructor


Gast
2006-10-19, 16:32:15
Hi,
hier einmal wichtige Funktion derTextList Klasse:

TextList::TextList(void)
{
this->runner=new LineNode();
this->footer=new LineNode();
this->header=new LineNode();
this->header->appendNextNode(footer);
this->numofLines=0;
}
TextList::~TextList(void)
{
system("pause");
this->runner=header->getNext();
LineNode *tmp;
int num=0;
while(num!=this->numberofLines())
{
std::cout<<num<<std::endl;
system("pause");
tmp=this->runner->getNext();
delete runner;
this->runner=tmp;
num++;

}
if(this->footer!='\0')
{
delete this->footer;
}
if(this->header!='\0')
{
delete this->header;
}
if(tmp!='\0')
{
delete tmp;
}
}
void TextList::appendLine(String s)
{
LineNode *foo;
if(s.getLength()<=255)
{
this->setRunner(this->numberofLines());
foo=new LineNode(&s);
runner->appendNextNode(foo);
// foo->printLine();
foo->appendNextNode(footer);
this->numofLines++;
}

}

void TextList::setRunner(int i)
{
this->runner=this->header->getNext();
int run=0;
while(this->runner!=this->footer&&run!=i)
{
run++;
this->runner=this->runner->getNext();
}
}

LineNode:

LineNode::LineNode(void)
{
this->data='\0';
this->next='\0';
}

LineNode::~LineNode(void)
{ // wird solange aufgerufen bis ein Stackoverflow auftritt
if(this->next!='\0')
{
delete next;
}
if(this->data!='\0')
{
delete this->data;
}
}
LineNode::LineNode(String *dat)
{

this->data=dat;
this->data->print();
this->next='\0';

}
LineNode::LineNode(const LineNode &data)
{
std::cout<<"Copy constructor"<<std::endl;
}
LineNode * LineNode::getNext()
{
return this->next;
}
void LineNode::appendNextNode(LineNode *node)
{ this->next=node;


}
void LineNode::printLine()
{
this->data->print();
}
void LineNode::appendNextNode(LineNode *node)
{ this->next=node;


}

String Class

String::String(void)
{
this->data='\0';
}

String::~String(void)
{
system("pause");
std::cout<<"Gehe in den String Destructor"<<std::endl;
if(this->data!='\0')
{
delete [] this->data;
}

}
String::String(char *content)
{
int count=0;
while(content[count]!='\0')
{
count++;
}
count++;

this->data=new char[count];
memcpy(data,content,count);
}
String::String(const String & s)
{
int sum=0;
while(s.data[sum]!='\0')
{
sum++;
}



this->data=new char[sum];
memcpy(this->data,s.data,sum);
std::cout<<"Leaving Copy Constructir"<<std::endl;
//s=new String(s.data);
}

int String::getLength()
{
int sum=0;
while(this->data[sum]!='\0')
{
sum++;

}

return sum;
}
void String::print()
{

std::cout<<this->data<<std::endl;
}

Geteste wurde der Code mit folgenden Aufrufen:

TextList *s=new TextList();
s->appendLine("HALLO");
s->appendLine("WELT");
system("pause");
delete s; // Hier beginnt das Übel^^


Wie kann es überhaupt zu sowas kommen?

Neomi
2006-10-20, 00:16:39
Die Methode "setRunner" arbeitet unsauber, dein Runner ist hinterher identisch mit dem Footer. In "appendLine" setzt du damit foo quasi als Nachfolger vom Footer und den Footer als Nachfolger von foo. Wenn du jetzt den Footer löschen willst, dann löscht er in seinem Destruktor erst foo, foo dagegen in seinem Destruktor erst den Footer. Du hast eine Endlosschleife in dieser Rekursion, die bei jedem neuen Destruktor-Aufruf den Stack ein wenig mehr beansprucht, bis er dann überläuft.

PS: dein Code sieht ziemlich seltsam aus. Warum vergleichst du Pointer mit '\0', also einem char? Direkt 0 oder NULL wäre leserlicher. Außerdem mußt du bei delete nicht vorher auf NULL prüfen, ein "delete NULL" ist sauber und macht exakt gar nichts.

Gast
2006-10-20, 11:04:38
Danke, der Stackoverflow ist weg. Jetzt muss ich nur noch einen kleinen Speicherzugriffsfehler beheben.