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:106
ich 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
struct
nehmen? Ich dachte, struct sei wieclass
, nur dass standardmäßig aufpublic
stattprivate
ist. 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
public
statt
private
ist.
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
class
oderstruct
Member enthält, die keine PODs sind (wiestd::string
oderstd::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.