2016-11-21 4 views
0

Wie ich las, gibt es eine Notwendigkeit, free() zu verwenden, ABER was passiert als nächstes? Ich meine, wenn ich so etwas bekam:Mit free(), was passiert später?

char word[] = "abc"; 
char *copy; 
copy = (char*) malloc(sizeof(char) * (strlen(word) + 1)); 
strcpy(copy, word); 
free(copy); 
printf("%s", copy); 

Es wird mich „abc“ schreiben. Warum?

+6

befreit Zugriff auf Speicher löst * undefiniertes Verhalten *. Es gibt kein "warum". Alles kann passieren. (Und höre auf, das Ergebnis von "malloc" zu werfen). – AnT

+0

Mögliches Duplikat von [malloc/free. kann aus dem freigegebenen Speicher lesen] (http://stackoverflow.com/questions/9673733/malloc-free-can-read-from-freed-memory) –

Antwort

4

Nach der Verwendung von free(), Ihr Zeiger copy noch auf die gleiche Speicherstelle verweist. free() löscht nicht wirklich, was dort im Speicher geschrieben ist, sondern sagt der Speicherverwaltung, dass Sie diesen Teil des Speichers nicht mehr benötigen. Deshalb gibt es immer noch abc aus. Ihr Betriebssystem könnte diesen Speicher jedoch einer anderen Anwendung oder einer neuen Anwendung zugewiesen haben, die Sie in Ihrer Anwendung zugewiesen haben. Wenn Sie Pech haben, erhalten Sie einen Segmentierungsfehler. Hier

+4

Ich würde vielleicht das zu "Wenn Sie GLÜCKLICH sind, werden Sie bekommen ein Segmentierungsfehler " – schil227

+0

Sie haben natürlich Recht. Wenn Sie Pech haben, überschreiben Sie den benutzten Speicher ohne irgendeine Warnung oder Fehler, und fragen sich obskure Bugs. – clocktown

2

free() Die Zuordnung des Speichers, der zuvor von einem Calloc, malloc oder realloc zugewiesen wurde, wird aufgehoben. Sie sollten nicht auf Speicher zugreifen, der frei ist, da das Verhalten nicht definiert ist. Es ist nur ein Zufall, dass es immer noch seinen vorherigen Inhalt enthält.

Es ist eine gute Idee, Werkzeuge als Valgrind zu verwenden, die Ihnen (unter anderem) sagen können, ob Sie versuchen, auf freigegebenen Speicher zuzugreifen. In Linux-Terminal, können Sie es wie folgt tun:

valgrind ./yourProgram

0

ist es explayned recht gut:

C Reference -- free()

Aufheben der Zuordnung von Speicher bedeutet nicht, gibt es nicht mehr Daten.

Der Speicher ist nur für neue Zuordnungen frei.

Der Zugriff darauf führt zu einem nicht definierten Verhalten.

0

Wie bereits erwähnt, ist das Verhalten nicht definiert, wenn der Code auf einen freigegebenen Zeiger verweist. In diesem Fall liest du es. Es wäre jedoch höchstwahrscheinlich nicht möglich, darauf zu schreiben, und Sie sollten einen Segmentierungsfehler sehen.

Ich empfehle, dass Sie es mit dem MALLOCDEBUG ausführen (z. B. unter AIX wäre es MALLOCDEBUG=validate_ptrs) oder eine ähnliche Umgebungsvariable auf Ihrer Plattform, so dass Sie diesen Fehler finden. Das Aktivieren von MALLOCDEBUG kann jedoch schwerwiegende Auswirkungen auf die Leistung Ihres Programms haben. Eine Alternative ist, Ihre eigene freie Routine zu schreiben, die auch die befreiten Zeiger setzen explizit wie unten dargestellt auf NULL:

#define MYFREE(x) do { free((x)); (x) = NULL; } while(0);