"Komfort" bei malloc
-
plizzz schrieb:
Ich wollte lediglich wissen, ob es nicht evtl. eine übersichtlichere Methode gibt, die ganzen malloc-Abfragen zu realisieren, anstatt irgendwelche Rückgabewerte durch die Funktionen durchzureichen. Da es da scheinbar keine eierlegende Wollmilchsau in dieser Angelegenheit gibt ...
Du hast schon recht, die probate Methode ist das Durchreichen von Errorleveln, weil:
- so goto- Zeugs ist super für lokale Cleanups, exit und anderes Brutalo- Zeugs hilft wenig bei der Fehlersuche.
- Du kannst je nach call depth differenzierte Fehlerbehandlungsstrategien ansetzen.Eigentlich ist es wichtiger, mal ein einheitliches Schema aufzusetzen. Ich bin mal so frech und sage, wenn alles gutgegangen ist, muß man dem nichts hinzufügen und das gibt den Rückgabewert 0. Dann kann ich dem Nicht- Null- Fall zigtausend Infos mitgeben, was gerade gekrackst hat, muß ja nicht nur malloc() sein.
Man kann dadurch an jedem Rückgabelevel entscheiden, was man tun muß und ist nur selten auf Überlegungen angewiesen, was das OS denn jetzt macht.
-
-
plizzz schrieb:
Ich wollte lediglich wissen, ob es nicht evtl. eine übersichtlichere Methode gibt, die ganzen malloc-Abfragen zu realisieren, anstatt irgendwelche Rückgabewerte durch die Funktionen durchzureichen.
Dynamische Sprünge nach aussen gibt es, sind schon erwähnt worden. Ist vielleicht in manchen Fällen besser, als Kaskaden von Wert-Übergaben einzurichten, wenn man in der Mitte gar nichts mit den Werten anstellen will.
_matze schrieb:
Über die Stelle im Standard gab es schon mal eine Diskussion. Und auch damals habe ich mich gefragt, was man mit dieser Variante (Adresse für Puffer der Länge 0 zurückliefern) eigentlich bezwecken will...
Kann mich errinnern. Der Compiler darf dafür sorgen, dass eine Verwaltungsstruktur auf dem Heap erstellt wird, auch wenn der zugehörige Puffer die Länge 0 hat. Der einzige Sinn, den ich bis jetzt dahinter gefunden habe, war, dass damit die Tradition eingehalten wird, möglichst wenige Vorschriften zu machen. Immerhin könnte man sich vielleicht ein paar Prozessor-Takte sparen, wenn man nicht immer prüfen muss, ob der malloc-Parameter 0 ist.
-
noobLolo schrieb:
NULL ist doch die einzige möglichkeit einen fehler aus der function raus zu bringen, da ja jeder andere wert einen potentiellen speicher bereich darstellt. und ein aufruf mit 0 stellt ja streng genommen keinen fehler dar.
Nein, aber er ist sinnlos, wie schon auf der ersten Seite erwähnt wurde.
Ich habe zum Spass mal das gemacht:while(1) void *z = malloc(0);
Bei mir läuft der Speicher ganz langsam voll, VS 2005, ca 1.6 GB nach 5 Minuten.
Da offensichtlich free() bei malloc(0) nötig ist, würde ich lieber sicherstellen, dass im Programm kein malloc(0) vorkommt.
-
Z schrieb:
Bei mir läuft der Speicher ganz langsam voll, VS 2005, ca 1.6 GB nach 5 Minuten.
Wenn malloc(0) nicht NULL zurückgibt, muss man das natürlich wieder freigeben. Wenn malloc(0) NULL zurückgibt, schadet free() aber auch nicht. Am besten ruft man also einfach zu jedem malloc free auf (wäre käme denn auch auf die Idee, das nicht zu tun?)
Wie gesagt kann malloc(0) vorkommen, wenn man sich einfach die Sonderbehandlung des Falls einer Größe von 0 spart.
Zum Beispiel: Man ließt irgendwelche Pakete aus einer Datei, wobei vorher jeweils die Paketgröße selber in der Datei steht. D.h. man ließt die Größe, malloct so viel Speicher, füllt ihn mit fread(buffer,size,1,f), und macht dann irgendwas damit, wobei man natürlich nur auf Arrayindizes 0 <= i < size zugreift.
Und wenn dann mal als Größe 0 gelesen wird (was ja vielleicht im Eingabeformat erlaubt ist) und malloc NULL liefert, funktioniert das immer noch völlig problemlos und standardkonform, ohne dass man diesen Fall gesondert behandelt haben muss.
-
Z schrieb:
Da offensichtlich free() bei malloc(0) nötig ist, würde ich lieber sicherstellen, dass im Programm kein malloc(0) vorkommt.
die sache ist, stell dir vor du gibst eine verkettete liste frei, in dieser liste sind per malloc(x) besorgte speicher blöcke abgelegt, die freigabe routine müßte nun immer checken ob auch was zum freigeben da ist, da ja ein free(NULL) auch was ganz schlimmes ist. also ist eigentlich das problem verschoben...
-
namespace invader schrieb:
Wie gesagt kann malloc(0) vorkommen, wenn man sich einfach die Sonderbehandlung des Falls einer Größe von 0 spart.
Das ist wohl Geschmackssache. Ich würde bei Werten aus nicht 100%ig vertrauenswürdiger Quelle immer auf Gültigkeit prüfen:
size_t n = irgendwo_hergeholt(); void *a; if (n > 0 && n <= MAX) a = malloc(n); else a = 0; // oder Fehlerbehandlung
-
namespace invader schrieb:
Wie gesagt kann malloc(0) vorkommen, wenn man sich einfach die Sonderbehandlung des Falls einer Größe von 0 spart.
Das klingt sinnvoll. Passt auch gut zum Standard, der vorschreibt, dass man den Zeiger von malloc(0) in jedem Fall an free() weitergeben darf, weil free(NULL) nichts tut.
noobLolo schrieb:
da ja ein free(NULL) auch was ganz schlimmes ist
Hättest nicht mehr oft umblättern müssen bis:
TC2 7.20.3.1 schrieb:
The free function causes the space pointed to by ptr to be deallocated, that is, made
available for further allocation. If ptr is a null pointer, no action occurs.
-
noobLolo schrieb:
Z schrieb:
Da offensichtlich free() bei malloc(0) nötig ist, würde ich lieber sicherstellen, dass im Programm kein malloc(0) vorkommt.
die sache ist, stell dir vor du gibst eine verkettete liste frei, in dieser liste sind per malloc(x) besorgte speicher blöcke abgelegt, die freigabe routine müßte nun immer checken ob auch was zum freigeben da ist, da ja ein free(NULL) auch was ganz schlimmes ist. also ist eigentlich das problem verschoben...
habs gerade nochmal getestet, free(0) geht, hab das iwie mit uninitialisierten pointern vertauscht
void *p; free(p);
=> *boom*
lg lolo
-
Z schrieb:
while(1) void *z = malloc(0);
Bei mir läuft der Speicher ganz langsam voll, VS 2005, ca 1.6 GB nach 5 Minuten.
Könnte mir jemand das erklären wieso das so ist?
Das ist irgendwie interessant auch wenn es blödsinnig aussieht.
-
woooooah schrieb:
Z schrieb:
while(1) void *z = malloc(0);
Bei mir läuft der Speicher ganz langsam voll, VS 2005, ca 1.6 GB nach 5 Minuten.
Könnte mir jemand das erklären wieso das so ist?
Das ist irgendwie interessant auch wenn es blödsinnig aussieht.wieso postest du in einen thread den du nicht gelesen hast?
-
noobLolo schrieb:
wieso postest du in einen thread den du nicht gelesen hast?
Ich hab den thread gelesen aber ich verstehe nicht wieso 0 bytes auch eine größe ist. was wird da angefordert?
-
evtl. hast auch ein problem mit deinem englisch
noobLolo schrieb:
...
schauen wir doch mal wie das in der glibc gemacht wurde;)/* Allocate an N-byte block of memory from the heap. If N is zero, allocate a 1-byte block. */ void * rpl_malloc (size_t n) { if (n == 0) n = 1; return malloc (n); }
...
-
danke nooblolo
hab es aus dem thread nicht rauslesen können!
-
heyhoi schrieb:
Ich hab den thread gelesen aber ich verstehe nicht wieso 0 bytes auch eine größe ist. was wird da angefordert?
Nichts. Was die Gnu libc tut, kannst du getrost ignorieren, ist ja keine Referenz-Implementation. Den Speicher verbraucht in dem Fall grossteils/ausschliesslich der Overhead.
-
Wird malloc() mit der Länge 0 aufgerufen ist vorher etwas schiefgelaufen.
Der Fall sollte normaerweise nicht auftreten bzw es sollte vorher geprüft
und reagiert werden.Kann das OS den Speicher nicht bereitstellen ist es so gut wie immer
sinnfrei, das Programm weiterlaufen zu lassen. Wozu auch ?
Also: exit() und raus.Da der Fall äußerst selten vorkommt (ok, bei mir. Mag bei anderen anders
aussehen) ignoriere ich "Nebeneffekte". Da soll sich das OS drum kümmern.
-
Scheppertreiber schrieb:
Kann das OS den Speicher nicht bereitstellen ist es so gut wie immer
sinnfrei, das Programm weiterlaufen zu lassen. Wozu auch ?
Also: exit() und raus.Na weil es vielleicht möglich sein sollte, dass ein bestimmter Programmteil aus irgendwelchen Gründen wie z.B. auch "nicht genug Speicher" nicht ausgeführt werden kann, ohne dass gleich die ganze Software böse abschmiert. Dann lieber die Rückgabe prüfen und ggf. eine Meldung raushauen, damit der User Bescheid weiß, aber nicht gleich den ganzen Prozess abschießen.
-
_matze schrieb:
Na weil es vielleicht möglich sein sollte, dass ein bestimmter Programmteil aus irgendwelchen Gründen wie z.B. auch "nicht genug Speicher" nicht ausgeführt werden kann, ohne dass gleich die ganze Software böse abschmiert. Dann lieber die Rückgabe prüfen und ggf. eine Meldung raushauen, damit der User Bescheid weiß, aber nicht gleich den ganzen Prozess abschießen.
Ok, das hängt von ... ab. In den meisten Fällen hat es ja einen Grund, Speicher
vom OS anzufordern. Klar sind Fälle denk- und konstruierbar wo das Programm auch
ohne weiterlaufen oder sich kontrolliert beenden kann. Nur, bevor ich mir Daten
schieße, lieber abbrechen und nach der Ursache suchen und diese beheben.
-
Scheppertreiber schrieb:
_matze schrieb:
Na weil es vielleicht möglich sein sollte, dass ein bestimmter Programmteil aus irgendwelchen Gründen wie z.B. auch "nicht genug Speicher" nicht ausgeführt werden kann, ohne dass gleich die ganze Software böse abschmiert. Dann lieber die Rückgabe prüfen und ggf. eine Meldung raushauen, damit der User Bescheid weiß, aber nicht gleich den ganzen Prozess abschießen.
Ok, das hängt von ... ab. In den meisten Fällen hat es ja einen Grund, Speicher
vom OS anzufordern. Klar sind Fälle denk- und konstruierbar wo das Programm auch
ohne weiterlaufen oder sich kontrolliert beenden kann. Nur, bevor ich mir Daten
schieße, lieber abbrechen und nach der Ursache suchen und diese beheben.Daraus lässt sich schliessen, dass Programme, die unbedingt immer laufen müssen, malloc nicht benutzen dürfen.
-
Wieso ?