Problem mit doppelt verketteter Liste
-
Hallo liebe Gemeinde,
ich habe ein kleines Problem mit einer Aufgabe... Ziel ist es eine Adressverwaltung mit doppelt verketteter Liste zu realisieren.
Jedoch stürzt mir das Programm jedes mal ab, wenn ich versuche einen Namen zu speichern. Ich hänge den Quelltext mal an. Der Fehler passiert in der main() an der Stelle, an der der Name gespeichert werden soll.
Ich hoffe mir kann geholfen werden

Vielen Dank schonmal im Voraus!
Mit freundlichen Grüßen,
cattweasel#include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> using namespace std; struct adresse { struct adresse *links; struct adresse *rechts; string name; }; struct adresse * neue_liste() { struct adresse *temp = (struct adresse*) malloc(sizeof(struct adresse)); temp->name; temp->rechts = temp; temp->links = temp; return temp; } struct adresse * eintrag_einfuegen(struct adresse *list, string name) { struct adresse *temp = (struct adresse *) malloc(sizeof(struct adresse)); temp->name = name; temp->links = list; temp->rechts = list->rechts; list->rechts = temp; temp->rechts->links = temp; return temp; } struct adresse * eintrag_loeschen(struct adresse *list) { list->rechts->links = list->links; list->links->rechts = list->rechts; return list->links; } struct adresse * eintrag_suchen(struct adresse *list, string name) { struct adresse *head = list; struct adresse *current = list; if (head->name == name) { return head; } while (head != (current->rechts)) { if (current->name == name) { return current; } } return false; } struct adresse * eintrag_ausgeben(struct adresse *list, string name) { struct adresse *current = eintrag_suchen(list, name); if (current != false) { cout << current->name << endl; } else { cout << "Der Eintrag konnte nicht gefunden werden." << endl; } } struct adresse * eintraege_ausgeben(struct adresse *list) { struct adresse *head = list; struct adresse *current = list; cout << head->name << endl; while (head != (current = current->rechts)) { cout << current->name << endl; } } int main(int argc, char** argv) { struct adresse *head = neue_liste(); struct adresse *current = head; //int eingabe = -1; string name; /*string strasse; char plz[5]; string ort; char geschlecht[1];*/ // WARUM GEHT DAS NICHT ?!?!?!?! name = "Max Mustermann"; current = eintrag_einfuegen(current, name); /*while (eingabe != 0) { cout << "HAUPTMENU" << endl << endl; cout << "1 - neue Adresse einfuegen" << endl; cout << "2 - Adresse suchen" << endl; cout << "3 - alle Adressen anzeigen" << endl; cout << "4 - Adresse loeschen" << endl; cout << "5 - Adresse ausgeben" << endl << endl; cout << "0 - Programm beenden" << endl << endl; cout << "Eingabe: "; cin >> eingabe; cout << endl << endl; if (eingabe == 1) { cout << "Name der Person: "; cin >> name; cout << "Strasse und Hausnummer: "; cin >> strasse; cout << "Postleitzahl: "; cin >> plz; cout << "Wohnort: "; cin >> ort; cout << "Geschlecht (m/w): "; cin >> geschlecht; // current = eintrag_einfuegen(current, name, strasse, plz, ort, geschlecht); } if (eingabe == 2) { cout << "Suchanfrage: "; cin >> name; current = eintrag_suchen(current, name); if (current != false) { cout << current->name << endl; } else { cout << "Der Eintrag konnte nicht gefunden werden." << endl; } } if (eingabe == 3) { eintraege_ausgeben(current); } if (eingabe == 4) { cout << "Name der Person: "; cin >> name; current = eintrag_suchen(current, name); if (current != false) { current = eintrag_loeschen(current); } else { cout << "Der Eintrag konnte nicht gefunden werden." << endl; } } if (eingabe == 5) { eintraege_ausgeben(current); } }*/ return 0; }
-
In den Zeilen 17 und 29 legst Du mit malloc zwar Speicher für ein Objekt des Tys 'adresse' an, rufst aber den Konstruktor des Members 'name' nicht auf. Damit erhälst Du uninitialisierten Speicher mit undefiniertem Verhalten.
Ersetze die Zeilen jeweils durch
struct adresse *temp = new adresse;dann wird auch der Defaultkonstruktor von string aufgerufen.
malloc wird in C++ normalerweise nicht mehr benutzt.
Ersetze noch #include <string.h> durch #include <string> und streiche die sonstigen #include <*.h>.
-
Hallo Werner,
vielen Dank für deine Hilfe. Ist auch irgendwie logisch... Fraglich warum ich nicht selbst darauf gekommen bin.
Jetzt funktioniert es.
Vielen Dank!!!
-
#include <iostream> #include <string> using namespace std; struct Adresse { Adresse *links; Adresse *rechts; string name; }; Adresse* create(string name) { Adresse *temp = new Adresse; temp->name = name; temp->rechts = 0; temp->links = 0; return temp; } Adresse* push_back(Adresse *list, string name) { Adresse *temp = new Adresse; temp->name = name; temp->links = list; temp->rechts = 0; list->rechts = temp; return temp; } void erase(Adresse *list) { if(list->links == 0 && list->rechts == 0){} else if(list->links == 0){list->rechts->links = 0;} else if(list->rechts == 0){list->links->rechts = 0;} else { list->links->rechts = list->rechts; list->rechts->links = list->links; } delete list; } void show(Adresse *beginn) { Adresse *current = beginn; cout << beginn->name.c_str() << "\n"; while (current->rechts != 0) { current = current->rechts; cout << current->name.c_str() << "\n"; } cout << endl; } void show_r(Adresse *end) { Adresse *current = end; cout << end->name.c_str() << "\n"; while (current->links != 0) { current = current->links; cout << current->name.c_str() << "\n"; } cout << endl; } int main(int argc, char** argv) { Adresse *head = create("Mueller Schultz"); Adresse *current = head; current = push_back(current, "Max Mustermann"); Adresse *premove = current; current = push_back(current, "Ich bin ein Star"); current = push_back(current, "holt mich hier raus"); show(head); show_r(current); erase(premove); show(head); show_r(current); return 0; }
-
Hallo Mischmasch,
das ist ja fast schon wie im Himmel hier

Wenn du mir jetzt noch verrätst, wie ich nach Namen suchen kann bin ich komplett glücklich.
Mit freundlichen Grüßen,
cattweasel
-
#include <iostream> #include <string> using namespace std; struct Adresse { Adresse *links; Adresse *rechts; string name; }; Adresse* create(string name) { Adresse *temp = new Adresse; temp->name = name; temp->rechts = 0; temp->links = 0; return temp; } Adresse* push_back(Adresse *list, string name) { Adresse *temp = new Adresse; temp->name = name; temp->links = list; temp->rechts = 0; list->rechts = temp; return temp; } Adresse* search(Adresse *list, string name) { if(list->name == name) return list; while(list->rechts != 0) { list = list->rechts; if(list->name == name) return list; } return 0; } void print(Adresse *list) { cout << list->name.c_str() << "\n"; } void erase(Adresse *list) { if(list->links == 0 && list->rechts == 0){} else if(list->links == 0){list->rechts->links = 0;} else if(list->rechts == 0){list->links->rechts = 0;} else { list->links->rechts = list->rechts; list->rechts->links = list->links; } delete list; } void show(Adresse *current) { print(current); while (current->rechts != 0) { current = current->rechts; print(current); } cout << endl; } void show_r(Adresse *current) { print(current); while (current->links != 0) { current = current->links; print(current); } cout << endl; } int main(int argc, char** argv) { Adresse *head = create("Mueller Schultz"); Adresse *current = head; current = push_back(current, "Max Mustermann"); Adresse *premove = current; current = push_back(current, "Ich bin ein Star"); current = push_back(current, "holt mich hier raus"); show(head); show_r(current); erase(premove); show(head); show_r(current); Adresse *psearch = search(head, "Mueller Schultz"); if(psearch != 0) print(psearch); return 0; }
-
Hallo Mischmasch,
ich habe gestern ganz vergessen mich noch bei dir zu bedanken.
Das möchte ich jetzt natürlich noch nachholen: Vielen Dank noch einmal!!!Aus dem Quelltext, den du mir geliefert hast, konnte ich Problemlos und ohne Vorkenntnisse in C++ meine Praktikumsaufgabe lösen

Mit freundlichen Grüßen,
cattweasel
-
cattweasel schrieb:
Hallo Mischmasch,
ich habe gestern ganz vergessen mich noch bei dir zu bedanken.
Das möchte ich jetzt natürlich noch nachholen: Vielen Dank noch einmal!!!Aus dem Quelltext, den du mir geliefert hast, konnte ich Problemlos und ohne Vorkenntnisse in C++ meine Praktikumsaufgabe lösen

Mit freundlichen Grüßen,
cattweaselDas mag zwar ein guter Ansatz in C sein, aber in C++ kann man das besser lösen. Stattdessen wären hier nämlich Klassen unter Nutzung von RAII angebracht gewesen.
Es findet auch keine Freigabe des reservierten Speichers statt. Insgesamt ist der Code daher als schlecht zu bewerten. Insbesondere unter dem Aspekt, dass es um C++ geht.
-
jghjgh schrieb:
Es findet auch keine Freigabe des reservierten Speichers statt. Insgesamt ist der Code daher als schlecht zu bewerten.
void erase(Adresse *list) { // ... delete list; }Die Bewertung des Codes ist bedeutungslos. Der Eleve hat verkettete Listen verstanden und somit das Ziel erreicht. Sprachspezifische Details sind überflüssiger Balast.
-
asdasd schrieb:
jghjgh schrieb:
Es findet auch keine Freigabe des reservierten Speichers statt. Insgesamt ist der Code daher als schlecht zu bewerten.
void erase(Adresse *list) { // ... delete list; }Die Bewertung des Codes ist bedeutungslos. Der Eleve hat verkettete Listen verstanden und somit das Ziel erreicht. Sprachspezifische Details sind überflüssiger Balast.
push_back(...) und create(...) haben jeweils ein new
erase(...) hat ein delete. Die erase(...) Funktion löscht dementsprechend nur 1 Element aus der Liste raus und zwar das, welches übergeben wird. Nach dem Aufruf von Erase kann man den übergebenen Pointer nicht mehr nutzen, darauf muss man dann achten. Im Code ist auch erkennbar, dass der reservierte Speicher nicht wieder freigegeben wird. Man brauch nur die new und delete aufrufe mal zählen und merkt, dass es nicht aufgeht.Der Code ist gültig, aber unsicher und unvollständig.
-
Code ist ungut schrieb:
Der Code ist gültig, aber unsicher und unvollständig.
Was für 99% aller Hausaufgaben gilt. Aber, wie gesagt, darauf kommt es nicht an.
Sicher könnte man hingehen und vor Programmende noch die gesamte Liste abräumen, oder eine Funktion bauen, die das übernimmt. Ist aber unnötig.