Forum: Compiler & IDEs malloc() - free() - Zeigermanipulation


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

nehmen wir an, ich hätte folgende, aufwendige Funktion:
1
void foo(void)
2
{
3
    uint8_t *a = malloc(10);
4
    a++;
5
    free(a);
6
}

Habe ich da ein Speicherleck gebaut?

Sprich: verlangt free(), das seine Eingabe auf den Anfang des 
freigegebenen Speicherbereichs zeigte, oder nur in diesen 
Speicherbereich?

Und wo finde ich das im Standard?

Viele Grüße
W.T.

von Markus F. (mfro)


Lesenswert?

Walter T. schrieb:
> Habe ich da ein Speicherleck gebaut?

Nein, Du hast Schlimmeres als das gebastelt.

Ein free() mit einer Adresse, die vorher nicht per malloc() allokiert 
(oder mit einer, die bereits freigegeben) wurde, ist nicht nur ein 
Speicherleck, sondern undefined behaviour.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf
1
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. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

Da dein Argument an free() kein "pointer earlier returnd by a memory 
management function" ist, ist das Verhalten undefiniert

von Walter T. (nicolas)


Lesenswert?

Michael R. 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. Otherwise, if the argument does not match a
> pointer earlier returned by a memory management function, or if the
> space has been deallocated by a call to free or realloc, the behavior is
> undefined.

Danke! Das ist eine Begründung.

Fun-Fact: Obengenannte Funktion lässt sich ohne Warnungen Kompilieren 
und bringt ein Programm beim Aufruf zuverlässig zum Absturz.

von och nöö (Gast)


Lesenswert?

Walter T. schrieb:
> Fun-Fact: Obengenannte Funktion lässt sich ohne Warnungen Kompilieren

Wie sollte dein Compiler auch "riechen" wo dein Pointer
hinzeigt wenn du free() aufrufst?

In deinem Fall wird bzw würde er das berechnen können, aber im
allgemeinen Fall wohl nicht.

von Markus F. (mfro)


Lesenswert?

Im simpelsten Fall ist die Freelist deiner dynamischen 
Speicherverwaltung nur eine verkettete Liste von Speicherblöcken.

Dazu allokiert malloc() ein paar Bytes mehr, als Du eigentlich haben 
wolltest vor dem reservierten Speicherblock und bringt dort seine 
Verwaltungsinformationen unter (die Blockverkettung und die Info, wie 
gross der allokierte Block ist).

Wenn Du nun irgendeine Adresse in free() reinsteckst, werden die Bytes 
vor dieser Adresse als Verwaltungsinformation interpretiert und 
versucht, einen Speicherblock aus einer verketteten Liste auszuketten, 
die gar keine ist. Das muss natürlich schief gehen.

Manche dynamischen Speicherverwaltungen lassen einen "Debug-Modus" zu, 
bei dem die Verwaltungsinformationen über "magic words" identifiziert 
werden (s. z.B. mprobe() in der GNU C-Library).

von Irgendwer (Gast)


Lesenswert?

Walter T. schrieb:
> und bringt ein Programm beim Aufruf zuverlässig zum Absturz.

Selbst darauf kannst du dich nicht verlassen. Das Gebilde kann auch 
beliebige andere Seiteneffekte verursachen die dann unter Umständen 
recht schwer zu finden sind.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.