2010-12-08 20 views
2
#include <stdio.h> 
int main() 

{ 

    int *p = (int *)malloc((100*sizeof(int))); 

    p++; 

    free(p); 

/* do something */ 

return 0; 

} 

Fragen:C Frage auf frei()

  1. Wird der Speicher von der Stelle beginnen p + 1 frei sein (zB wenn malloc 0x1000 zurück, befreit der Speicher wird von 0x1004 sein, ein unter der Annahme, 4 Byte ganze Zahl)?

  2. Gibt es anypitfalls dieses Codes abgesehen von der Tatsache, dass die 4 Bytes von 0x1000 (falls malloc 0x1000 zurück) nicht verwendbar sind (es sei denn Sie eine P-- tun und verwenden Sie die Adresse)

+0

Ich habe Ihre Formatierung korrigiert. Bitte lesen Sie die Bearbeitungshilfe, um zu sehen, wie Sie den Code richtig formatieren. –

+1

Für einige Hinweise nicht direkt mit Ihrer Frage, aber mit Ihrem Code: (1) in C, werfen Sie nicht die Rückkehr von 'malloc' Dies kann den Bug von "stdlib.h", wie in Ihrem verstecken Beispiel. Ihr Code kann dann fehlschlagen, wenn Sie von einer 32-Bit-Maschine zu 64 Bit wechseln. (2) nicht "neu erfinden" eine Unterschrift für "Haupt". In C 'int main()' und 'int main (void)' sind nicht gleich. –

Antwort

0

Dieser Code wird einfach nicht funktionieren - Sie können nur Zeiger freigeben, die von malloc oder einer ähnlichen Funktion zugewiesen wurden, Sie können keinen Teil des zugewiesenen Speicherbereichs freigeben.

12

Das ist undefiniertes Verhalten - Sie müssen genau den gleichen Zeiger auf free() übergeben, wie Sie von malloc() erhalten haben. Mit Ihrem Code kann alles passieren - wahrscheinlich Heap wird beschädigt.

Denken Sie auf diese Weise. free() hat nur einen Parameter, also muss er ableiten, was genau von diesem einen Parameter frei ist. Es gibt keine Möglichkeit, "weniger Speicher freizugeben" - entweder wird es alles befreien (Abzug, der dazu benötigt wird, wird sehr zeitaufwendig sein), oder etwas Schlimmes passiert - Letzteres ist wahrscheinlicher. Du solltest nichts annehmen, tu das einfach nicht.

1

Der Aufruf von free() wird fehlschlagen, weil p nicht mehr die Adresse eines Blocks ist, der mit malloc() zugewiesen wurde.

+0

Nicht unbedingt wird es fehlschlagen. Es kann verheerende Haufen verderben und Sie werden es erst viel später bemerken. – sharptooth

+0

es ist undefiniertes Verhalten wie 'sharptooth' oben vorgeschlagen. free() wird nicht fehlschlagen. – steve

+0

@steve: Vielleicht wird es scheitern. – sharptooth

0

Hey habe ich versucht, diesen Code über gcc und es hörte auf, mit:

*** glibc detected *** ./a.out: free(): invalid pointer: 0x0829600c *** 
======= Backtrace: ========= 
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x7be591] 
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x7bfde8] 
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x7c2ecd] 

So wie pro Ihre erste Antwort, die Sie nicht den nächsten Speicherplatz frei. und für die zweite Frage: und die vier Bytes werden nicht verwendbar sein, es sei denn, Sie p-- und dieser Code funktioniert gut, es sei denn, Sie ändern den Inhalt des nächsten Speicherplatzes und Sie können den zugewiesenen Speicherort verwenden, indem Sie p- -

+0

"Diese spezielle C++ Implementierung" bedeutet nicht unbedingt "das ist die richtige Antwort". Es ist die richtige Antwort für diese Implementierung, aber nicht für die Sprache "C++". –

0

in Standard ist dieses Verhalten "undefined", aber eigentlich wird nichts freigegeben werden. Der Grund ist, dass was malloc hält eine Liste der Brocken, die es zugewiesen hatte, jedes Stück wird durch seine beginnend Adresse identifiziert. p + 1 ist nicht auf dieser Liste, so frei wird ein Stück frei zu finden, und wird nichts tun.