Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
Aufgabe 3 malloc
Nehmen wir an ich habe schon ein paar mal malloc und free aufgerufen, und rufe jetzt malloc(100) auf. Malloc findet jetzt einen freien Speicherblock mit zb. der Größe 105 Bytes, also genug um zu allokieren, aber nicht genug um ein mblock für den Speicherrest einzurichten. Was mach ich dann?
Dann übersprichst du diesen Block und suchst weiter mit dem nächsten freien Block in deiner Freispeicherliste oder, wenn das der letzte war, gibst [m]NULL[/m] zurück ([m]errno[/m]) nicht vergessen.
Das ist doch doof wenn man genügend Speicher hat aber nicht allokiert?
Vielleicht habe ich mich auch missverständlich ausgedrückt.
Der Speicherblock ist an sich groß genug ist, um zu allokieren. Der verbleibende Speicher, der für die Allokation nicht gebraucht wird, wird ja dann normal einfach für weitere Allokierungen freigegeben, indem man ein mblock an den Anfang stellt. Was ist aber, wenn dieser verbleibender Speicher aber nicht genügend Speicher für ein mblock besitzt? Ohne mblock gibt es ja keine Möglichkeit mehr, jemals wieder auf diesen verbleinden Speicher zuzugreifen
Oh, ich hab das falsch verstanden. Wenn das “neue” [m]mblock[/m]-Struct gerade nicht mehr reinpasst, aber groß genug für die Anforderung ist, dann verwendest du den Block und die 5 Byte sind bei dieser Allokation Verschnitt. Pass aber auf die die Größe auf, dass auch wieder 105 Bytes nach dem Freigeben zur Verfügung stehen. Falls du diesen Bereich freigibst und direkt danach [m]malloc(105)[/m] machst, dann muss der Block verwendet werden.
Danke!
Hmm das ist aber auch nicht schön, weil wenn dann der Speicherblock dahinter freigegeben wird, ist dieser Speicherrest immer noch belegt, obwohl er theoretisch jetzt nutzbar wäre…Aber das ist wohl einfach das kleinere Übel oder?
Und noch zwei Fragen:
Ich habe bereits in der letzten Aufgabe nicht verstanden wie das mit errno und perror geht.
Laut Übungsfolie ist perror ja im Grunde einfach eine Textausgabe, die hier benutzt wird um Fehler auszugeben? Das einzige besondere gegenüber zb. printf wäre dann das mit errno. Das soll eine globale Variable sein, die auch den (reservierten) Wert 0 annehmen kann.
Ist das dann ein int? Ein char? Oder doch ein String, da “Fehlercode”? Und heißt dann errno setzten dass ich mir einfach eine globale Variable mit dem Namen errno anlege?
Was hat das dann mit perror zu tun und woher krieg ich den Fehlercode den ich in errno speichern soll? Ich bin da wirklich verwirrt!
Und zu free():
In der Aufgabenstellung steht: “Die Funktion free() hängt den freizugebenden Speicherbereich wieder vorne in die Freispeicherliste ein”. Heißt das ich darf sie auch einfach gleich an head hängen? die Reihenfolge der freien Speicherblöcke in der Liste dürfte ja egal sein, vor allem da man sowieso nicht mit Nachbarn verschmelzen muss?
Ja. Der ist weg. Da kannst du mit dem aktuellen Setup nichts machen.
[m]man errno.h[/m] - [m]errno[/m] ist eine Integer-Variable, die du auf Konstanten setzen kannst. Der genaue Typ ist glaub ich nicht spezifiziert.
Nein, anlegen kannst du die nicht. Du musst den Header mit der Deklaration inkludieren ([m]#include <errno.h>[/m]) und dann einfach einen Wert zuweisen. [m]errno[/m] ist dabei lokal für den aktuellen Thread.
[m]man 3p malloc[/m] sagt dir unter „ERRROS“ welche Werte [m]errno[/m] annehmen kann. Den musst du dann einfach im Fehlerfall zuweisen.
[m]perror(3)[/m] ist einfach nur ein großes Switch, das für jeden Wert der [m]errno[/m] eine Fehlermeldung ausgibt.
Ja. Du fügst ihn vorne in die Liste ein.
Oke ich glaube ich hab das jetzt verstanden. Wenn also ein Fall eintritt der unter ERRORS steht, soll einfach zuerst errno auf den Code gesetzt werden und sofort danach perror aufgerufen werden?
Und da sich Fragen wie die Kanickel vermehren:
“if the argument does not match a pointer earlier returned by <alles mögliche an malloc Zeugs>, the behavior is undefined.” Also einfach den Fall nicht beachten, der Anwender muss sich selbst darum kümmern dass sein Parameter gültig ist?
VIelen Dank nochmal, ich wüsste nicht wie ich es sonst hinkriegen würde!
Fast. Du darfst nur kein [m]perror(3)[/m] aufrufen. Bibliotheksfunktionen sollten (praktisch) nie selbst Ausgaben erzeugen. Die gesetzte [m]errno[/m] liefert genug Informationen für den Aufrufer. Der kann dann z.B. das Problem ignorieren oder eine andere Fehlermeldung ausgeben oder [m]perro(3)[/m] aufrufen.
Nein. Du solltest das abfangen. Wenn du siehst, dass bei einem [m]free(3)[/m] oder [m]realloc(3)[/m] ein nicht-belegter Pointer reinkommt, dann solltest du [m]abort(3)[/m] aufrufen. Der Standard sagt nur, dass nicht definiert ist, wie man sich als Bibliothek verhalten muss.