Unklarere Segmentation Fault
-
Ich habe folgende Methode geschrieben:
void CandidatesTable::toString() { struct tm *tminfo; time_t now = time(0); cout << now << endl; tminfo = localtime( &now ); cout << endl << "Aktuelle Kandidaten von " << asctime( tminfo ); cout << "--------------------------------------------" << endl; for( int i = 0; i < length; ++i ) { time_t t_ = t[i]; tminfo = localtime( &t_ ); cout << (i+1) << ".\t" << names[i] << "\t\t" << llrs[i] << "\t" << tminfo->tm_hour << ":" << tminfo->tm_min << ":" << tminfo->tm_sec << "h" << endl; } cout << "--------------------------------------------" << endl; }Wenn mein Programm diese Methode aufruft, dann erhalte ich folgenden Fehler (gdb Ausgabe):
1279117548
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x48be8732
0x92dbae9e in __findenv ()
(gdb) up
#1 0x92dbae06 in getenv ()
(gdb) up
#2 0x92df05d4 in _st_tzset_basic ()
(gdb) up
#3 0x92df058c in localtime ()
(gdb) up
#4 0x00006568 in CandidatesTable::toString (this=0xbffff190) at CandidatesTable.cpp:144
144 tminfo = localtime( &now );
(gdb)Interessanterweise habe ich diese Methode auch in meinen Unit-Tests verwendet und da läuft es einfach durch ohne zu meckern.
Was ist denn hier jetzt los? Ich versteh das überhaupt nicht.

-
Okay, ich habe ein "make clean" und anschließend ein wieder ein make gemacht. Jetzt läuft es :). Danke fürs Lesen.
-
Hi HändyÄndy,
auch wenn dein ursprüngiches Problem bereits gelöst ist: Die Methode ist "nicht optimal" - sie tut nämlich etwas Anderes als man so spontan vermutet.
Mit "toString" wird in 99,9% der Fälle erwartet, dass man hinterher einen String in den Händen hält - und nicht, dass man auf der Konsole was ansehen kann.Entweder (falls du wirklich auf die Konsole ausgeben willst) würde ich sowas wie "print()" oder so erwarten.
Oder (falls es tatsächlich in einen String umgewandelt werden soll) du änderst toString() derart, dass es in einen ostringstream schreibt und gibst mittels ostringstream::str() einen string zurück.Aber: der toString-Gedanke kommt aus Java (ist auch nicht schlecht) und in C++ ist es bei sowas deutlich üblicher, den operator<<() zu überladen und den Aufrufer selbst entscheiden zu lassen, wohin er die Daten dann transferieren will (Konsole, string, file, Netzwerk, ....).
Wäre auch nicht schwer:// ruhig als freie Funktion - ist üblich und müllt nicht die CandidatesTable-Schnittstelle zu ostream& operator<<(ostream& ost, CandidatesTable const& c) { struct tm *tminfo; time_t now = time(0); ost << now << endl; tminfo = localtime( &now ); ost << endl << "Aktuelle Kandidaten von " << asctime( tminfo ); ost << "--------------------------------------------" << endl; for( int i = 0; i < length; ++i ) { time_t t_ = t[i]; tminfo = localtime( &t_ ); ost << (i+1) << ".\t" << c.names[i] << "\t\t" << c.llrs[i] << "\t" << tminfo->tm_hour << ":" << tminfo->tm_min << ":" << tminfo->tm_sec << "h" << endl; } ost << "--------------------------------------------" << endl; } // Aufruf easy: int main() { CandidatesTable c; // irgendwie konstruiert cout << c; // af Konsole ofstream out("CandidatesTable.out"); out << c; // identisch direkt in File myNetStream m; m << c; ...Gruß,
Simon2.