Probleme mit std::vector
-
Hallo,
An den markierten Stelle steigt das Programm aus mitProgram received signal SIGSEGV, Segmentation fault. 0x0043f83e in void std::_Construct<Person*, Person*>(Person**, Person* const&) (__p=0x101, __value=@0x3e3e38) at C:/Programme/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:81 81 ::new(static_cast<void*>(__p)) _T1(__value); (gdb) bt #0 0x0043f83e in void std::_Construct<Person*, Person*>(Person**, Person* const&) (__p=0x101, __value=@0x3e3e38) at C:/Programme/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:81 #1 0x0043da51 in std::vector<Person*, std::allocator<Person*> >::push_back(Person* const&) (this=0x22fe7c, __x=@0x3e3e38) at C:/Programme/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_vector.h:560 #2 0x00401b6b in main () at cpu.cpp:106ich verstehe nicht, warum sich der Vektor (s.u.) Dagegen sträubt, einen Person* aufzunehmen. Es liegt aber irgendwie am Vektor, wenn ich einen neuen erzeuge, funktioniert es, aber *nie* mit Film::personen. Wie kann das sein, wo ist der Unterschied, ob ich statt der Stelle schreibe:
vector<Person*> v; v.push_back(new Person());oder das schreibe was da unten steht? Aber leider funktioniert das da unten nicht, also muss da ja irgendwas noch anders sein...?
struct Film; struct Person{ string name; vector<Film*> filme; Person(): name(), filme() {} }; struct Film{ string name; vector<Person*> personen; Film(): name(), personen() {} }; struct Person_ptr_vergleicher{ string name; Person_ptr_vergleicher(Person*& p): name(p->name) {} bool operator()(Person*& p){ return name == p->name; } }; struct Film_ptr_vergleicher{ string name; Film_ptr_vergleicher(Film*& f): name(f->name) {} bool operator()(Film*& f){ return name == f->name; } }; int main(){ // Liste mit Namen, Filmen und deren Verbindung // Liste einlesen. vector<Person*> personen; vector<Film*> filme; ifstream cpu_daten("cpu-daten.txt"); for(;;){ string line; getline(cpu_daten, line); if(line.length() == 0) break; int delimPos = line.find_first_of('|'); string name = line.substr(0, delimPos); string film = line.substr(delimPos + 1); // Nachdem die Liste eingelesen wurde, in Listen speichern. Person* neue_person = new Person(); neue_person->name = name; Film* neuer_film; neuer_film->name = film; vector<Person*>::iterator person_iterator; vector<Film*>::iterator film_iterator; // Wenn bereits in Liste vorhanden, muss die Person/der Film nicht neu angelegt werden if((person_iterator = find_if(personen.begin(), personen.end(), Person_ptr_vergleicher(neue_person))) == personen.end()){ personen.push_back(neue_person); person_iterator = personen.end() - 1; } else delete neue_person; if((film_iterator = find_if(filme.begin(), filme.end(), Film_ptr_vergleicher(neuer_film))) == filme.end()){ filme.push_back(neuer_film); film_iterator = filme.end() - 1; } else delete neuer_film; // Anschliessend noch Person mit Film und umgekehrt assoziieren (*person_iterator)->filme.push_back(*film_iterator); =======>(*film_iterator)->personen.push_back(*person_iterator); } return 0; }Woran kann das liegen?
Grüße,
Fabian
-
Also was mir zuerst aufgefallen ist.
Entweder du arbeitest mit alten POD´s dann halte dich aber auch an deren Logik, oder du benutzt das C++ äquvivalentclass. Weiterhin, was soll das hier:struct Person{ string name; vector<Film*> filme; Person(): name(),//wie wäre es wenn du die mal initialisierst filme()//das selbe hier. {} };Holy Crap !? Aber das bezieht sich schon auf das oben gesagte.
-
piXelshooter schrieb:
Film* neuer_film;
neuer_film->name = film;Zugriff auf einen uninitialisierten Zeiger -> Undefiniertes Verhalten.
-
Firefighter schrieb:
Entweder du arbeitest mit alten POD´s dann halte dich aber auch an deren Logik, oder du benutzt das C++ äquvivalent
class.
was ist denn das für ein hinweis? was genau willst du damit sagen?
-
danke, MFK. Ziehmlich bitter, dass ich das die ganze Zeit überlesen hab, ich dachte wohl, wenn ich
new Person()geschrieben hab, habe ich auchnew Film()geschrieben... Was mich ein wenig wundert ist, dass mein Compiler (gcc) nicht warnt, wenn ich einen nicht-initialiserten Pointer verwende. Dafür wird es dann wahrscheinlich einen Grund geben, nicht zu warnen, denn so ein Fehler sieht für aus, als würde er sich relativ schnell einschleichen und sich gut automatisch feststellen lassen.Firefighter: Warum soll ich nicht
structnehmen? Ich dachte, struct sei wieclass, nur dass standardmäßig aufpublicstattprivateist. Ich weiß, ich sollte nicht direkt auf die Elementvariablen zugreifen, aber das Programm ist für eine kleine Aufgabe, daher denke ich, dass die Vorteile von »strengem« Vorgehen hier nicht wirklich zum Tragen kommen, die ganze Sache aber deutlich länger wird.
-
piXelshooter schrieb:
Ich dachte, struct sei wie
class, nur dass standardmäßig auf
publicstatt
privateist.
Da liegst Du richtig...
-
Firefighter schrieb:
Also was mir zuerst aufgefallen ist.
Entweder du arbeitest mit alten POD´s dann halte dich aber auch an deren Logik, oder du benutzt das C++ äquvivalentclass.Sobald eine
classoderstructMember enthält, die keine PODs sind (wiestd::stringoderstd::vector), ist sie auch selbst kein POD mehr, sondern ein Klassentyp. Und die explizite Initialisierung von Klassentypen ist nicht nötig, wenn diese einen Standardkonstruktor besitzen.