Verkettete Liste
-
Hallo!
Ich bin grade dabei im Zusammenhang mir WinGUI-C-Programmierung eine einfache verkettete Liste zu schreiben. Allerdings habe ich ein kleines Problem.
In der unterstrichenen Zeile(26) schreibt er mir nicht einfach die Adresse des allokierten Speichers in den Pointer, sondern bringt mir eine Zugriffsverletzung.
Ich hatte dieses Problem schonmal...damals hab ich es dann mit nem void-Pointer umgangen. Da ich mir aber sicher bin, dass es auch anders geht (wahrscheinlich sogar recht einfach und ich seh's nur mal wieder nicht ^^), wäre es nett, wenn mir jemand mit meinem Problem weiterhelfen würde!
Danke im Voraus!
MfG
Apokalypsusvoid H_OnLButtonDown( HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags ) { HDC hdc; LIST *plist, *phelp; hdc = GetDC(hwnd); TextOut (hdc, x, y, TEXT("+"), 1); ReleaseDC(hwnd, hdc); plist = (LIST *)malloc(sizeof(LIST)); plist->pl = NULL; plist->pos.x = x; plist->pos.y = y; if (plist != NULL) { phelp = plhead; if (plhead == NULL) plhead = plist; else { while (phelp != NULL) phelp = phelp->pl; } [u]phelp->pl = plist;[/u] } }
-
wenn plhead NULL ist, dann ist auch phelp NULL
-
Versteh etz nicht, was du mir damit sagen willst...
Er macht eigentlich alles so wie ich will (zum. laut Debugger)...nur die Unterstrichene Zeile funktioniert net so wie ich mir das vorgestellt habe.
Wenn deine Aussage allerdings irgendwie damit zusammenhängt, wäre ich für eine genauere Erklärung dankbar.
-
ok, sorry, etwas genauer:
du weist plhelp den wert von plhead zu:
phelp = plhead;
du überprüfst zwar ob plhead NULL ist und reagierst darauf:
if (plhead == NULL) plhead = plist; else { while (phelp != NULL) phelp = phelp->pl; }
wenn plhead vor der Überprüfung aber NULL war ist auch phelp immer noch NULL,
somit greifst du hier auf Speicheradresse 0 zu, was in die Hose gehen muss:phelp->pl = plist;
-
OK...Danke!
Hab es etz verstanden
Werde morgen folgenden Lösungsansatz versuchen:... if (plist != NULL) { phelp = plhead; if (plhead == NULL) { plhead = plist; phelp = plist; //<<< ÄNDERUNG } else { while (phelp != NULL) phelp = phelp->pl; } phelp->pl = plist; ...
Hoffe es bringt was...
-
So... irgendwie hab ich mich da wohl in was verrannt...grich des ganze net zum laufen. Es geht zwar jetzt schon besser als zuvor...sobald ich aber das zweite mal klicke kommt ein Fehler.
void H_OnLButtonDown( HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags ) { HDC hdc; LIST *plist, *phelp; hdc = GetDC(hwnd); TextOut (hdc, x, y, TEXT("+"), 1); ReleaseDC(hwnd, hdc); plist = (LIST *)malloc(sizeof(LIST)); if (plist != NULL) { plist->pl = NULL; plist->pos.x = x; plist->pos.y = y; if (plhead == NULL) plhead = plist; else { phelp = plhead; while (phelp) phelp = phelp->pl; phelp->pl = plist; } } else MessageBox( hwnd, "Kein Speicher!", "FEHLER", MB_ICONERROR); }
Irgendwas spinnt da... ich hab glaub ich einfach zu wenig Ahnung wie das mit den Pointern da genau abläuft...
Ich vermute momentan, dass es an der while-schleife hängt, weil er sich net ordentlich an den pl-Pointern durch die Liste arbeiten kann.
Bin für jeden Tipp und jede Erklärung dankbar.
Danke im Voraus!
Apokalypsus
-
ohne mich mit der programmlogik auseinander gesetzt zu haben, fällt mir
folgendes auf:plist = (LIST *)malloc(sizeof(LIST));
du allozierst bei jedem klick erneut speicher für plist.
nicht nur, dass du ein nettes memory leak eingebaut hast, da
du den speicher nicht mehr in dieser funktion freigibst :),
so kann dieser code auch keine verkettete liste sein.
die plist zeigervariable ist nach dem return aus der funktion
zerstört, demnach kannst du auch nicht erwarten, dass du
bei einem zweiten klick noch auf zugewiesene daten zugriff hast.edit: wenn du es als C code kompilierst, ist ein casten des void pointers
von malloc übrigens nicht notwendig. ein:plist = malloc(sizeof(LIST));
wäre ausreichend
-
Der Sinn des Programmes ist es gerade die Koordinaten der gedruckten "+" in einer verketteten Liste zu speichern und sie dann bei einer Paint-Message wieder neu auszugeben, dass sie nicht gelöscht werden.
Aber das mit den pl-Pointern... da hab ich momentan ein Brett vorm Kopf ich starr das Programm an und hab keine Idee...langsam nervt es mich...weil es leider momentan nicht ganz unwichtig is, dass ich das noch verstehe....schreib bald Prüfung in Informatik ^^.
-
da musst du den code aber komplett umkrempeln. für solch einfache sachen reicht ein
dynamisches array mit realloc() vollkommen aus. in der hoffnung du weist
was ich damit meine :). verkettete listen mögen kool aussehen, verkomplizieren
den code in deinem fall aber unnötig.
-
jo... das is mir auch klar...das problem an der sache is nur, dass die aufgabenstellung explizit eine verkettete liste verlangt...
das is ne alte prüfungsaufgabe. solche aufgaben sind ja bekanntlich nie sehr sinnvoll...
________________________________________________________
Edit:
Hab jetzt per mail vom Prof. die Lösung:void H_OnLButtonDown( HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags ) { HDC hdc; LIST *plist; hdc = GetDC(hwnd); TextOut (hdc, x, y, TEXT("+"), 1); ReleaseDC(hwnd, hdc); plist = (LIST *)malloc(sizeof(LIST)); if (plist != NULL) { plist->pl = plhead; plist->pos.x = x; plist->pos.y = y; plhead = plist; } else MessageBox( hwnd, "Kein Speicher!", "FEHLER", MB_ICONERROR); }
Muss etz nurnoch verstehen, was er da genau macht...