014
27.07.2010, 13:26 Uhr
0xdeadbeef
Gott (Operator)
|
Au weia, das leckt so jede Menge Speicher.
Also, Zeiger sind im Grunde ziemlich simpel - ein Zeiger zeigt. Man kann ihn irgendwohin zeigen lassen und nachkucken was da steht, wo er hin zeigt (und in der Umgebung). Was dir hier Knüppel zwischen die Beine wirft, ist Speicherverwaltung.
Was du mit new anforderst, musst du mit delete wieder freigeben. Was du mit new[] anforderst, musst du mit delete[] wieder freigeben. Du solltest also höllisch aufpassen, dass du keinen Speicher verlierst. Hier:
C++: |
Adresse* ua_neu = new Adresse[j+1]; for (i = 0; i < j+1; i++) { ua_neu[i].name = new char[80]; ua_neu[i].straße = new char[80]; ua_neu[i].stadt = new char[80]; } for (i = 0; i < j+1; i++) { strcpy(ua_neu[i].name, ""); strcpy(ua_neu[i].straße, ""); strcpy(ua_neu[i].stadt, ""); } std::copy(useradressen, useradressen + j, ua_neu); delete[]useradressen; useradressen = ua_neu; j++;
|
verlierst du eine Menge Speicher, weil du erst Speicheradressen in ua_neu speicherst und sie dann sofort wieder mit den alten aus useradressen überschreibst. Das einzige, was davon bleibt, ist ua_neu[j]. So könnte man es machen:
C++: |
Adresse* ua_neu = new Adresse[j+1];
std::copy(useradressen, useradressen + j, ua_neu); delete[] useradressen; useradressen = ua_neu;
ua_neu[j].name = new char[80]; ua_neu[j].straße = new char[80]; ua_neu[j].stadt = new char[80]; strcpy(ua_neu[j].name, ""); strcpy(ua_neu[j].straße, ""); strcpy(ua_neu[j].stadt, "");
j++;
|
...und du musst natürlich am Ende den Inhalt und useradressen auch freigeben. Habt ihr Konstruktoren und Destruktoren schon behandelt? Damit könnte man das nämlich deutlich besser organisieren.
Übrigens:
hauen dir die meisten C++-Compiler um die Ohren (die Form ist im Standard explizit verboten - main muss int zurückgeben). Soweit ich weiß, akzeptiert das heute nur noch MSVC aus Gründen der Abwärtskompatibilität mit Vorstandardcompilern. Ich weiß nicht, woher du diese Form hast, aber gewöhn sie dir ganz schnell wieder ab und such dir eine bessere (neuere) Lernquelle.
Der Hintergrund dabei ist, dass der Rückgabewert eines Programms von der umgebenden Shell ausgewertet werden kann. Ein Shellskript kann etwa etwas derartiges enthalten:
C++: |
if programm; then echo "Alles gut!" else echo "Ja scheiße, was mach ich jetzt?" fi
|
bzw. eine Batch-Datei
C++: |
programm if errorlevel 0 goto allesgut echo "Ja scheiße, was mach ich jetzt?" goto ende :allesgut echo "Alles gut!" :ende
|
Per Konvention bedeutet ein Rückgabewert von 0, dass alles gut gelaufen ist, alles andere wird als Fehlercode verstanden. Deshalb gibt es für main auch die Sonderregelung, dass, wenn kein return-Statement durchlaufen wird, 0 zurückgegeben wird. Das gilt aber nur für main! Nicht, dass du dich nachher für andere int-Funktionen darauf verlässt. -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra |