Probleme mit std::vector



  • Hallo,
    An den markierten Stelle steigt das Programm aus mit

    Program 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++ äquvivalent class . 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 auch new 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 wie class , nur dass standardmäßig auf public statt private 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++ äquvivalent class .

    Sobald eine class oder struct Member enthält, die keine PODs sind (wie std::string oder std::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.


Anmelden zum Antworten