struct foo
{
int a;
int b;
};
void* p = (void*)malloc(sizeof(struct foo));
((foo*)p)->a;//do something.
free(p);//Is this safe?
Antwort
Ja.
malloc liefert void *
und frei nimmt void *
, so einige Ihrer Würfe sind bedeutungslos, und du bist zu befreien immer ein void *
, auch wenn Sie mit einer anderen Art von Zeiger fangen.
Ja, es ist sicher.
Ja - free
nimmt einen Zeiger auf void, also wenn Sie es aufrufen, wird der Zeiger (implizit) auf einen Zeiger auf Void in jedem Fall umgewandelt.
Der Rest des Codes ist nicht ganz so sicher:
void* p = (void*)malloc(sizeof(foo));
Sie sollten nicht werfen die Rückkehr von malloc (in C). Dies kann den Fehler des Vergessens abdecken #include <stdlib.h>
Ja. Der Funktionsprototyp für free
ist auch:
void free(void *ptr);
Ja, es ist sicher. Bei der Zuweisung von Speicher verfolgt die Laufzeitbibliothek die Größe jeder Zuordnung. Wenn Sie free() aufrufen, sucht es die Adresse, und wenn es eine Zuordnung für diese Adresse findet, wird die richtige Menge an Speicher freigegeben (der Block, der an dieser Adresse zugewiesen wurde).
Vielleicht ist es nicht fühlen sicher wegen der Magie passiert hinter den Kulissen. Die C-Laufzeit und/oder das Betriebssystem selbst verfolgen aktiv den von malloc zurückgegebenen Speicher, einschließlich seiner Größe und seines Standorts. Obwohl es sich anfühlt, als würden Sie einen typlosen Zeiger wieder auf free() übergeben, übergeben Sie tatsächlich einen Verweis auf ein Objekt, das der Speichermanager aktiv verfolgt.
in C ist es vollkommen sicher, weil es keine Destruktoren zu nennen gibt.
Das Speichersystem verfolgt die Größe der Zuordnungen.
In C++ müssen Sie den gleichen Typ löschen, den Sie neu haben, einschließlich des delete [] -Operators, um neue Arrays zu löschen.
Dies ist nur um sicherzustellen, dass Destruktoren aufgerufen werden.
Ja, aber normalerweise ist es ein Zeichen für schlechtes Design. malloc() wird normalerweise zum Zuweisen von Puffern (große Arrays desselben primitiven Typs) oder von Objekten (Strukturen mit initialisierten Feldern) verwendet. so
unsigned char *rgba_buffer = malloc(width * hieght * 4);
/* use the buffer here */
free(rgba_buffer);
BITSTREAM *bs = bitstream("bitfile.boin");
/* use the bitstream here */
destroy_bitstream(bs);
typedef struct
{
FILE *fp;
unsigned char ch;
int index;
} BITSTREAM;
BITSTREAM *bitstream(const char *filename)
{
BITSTREAM *bs = malloc(sizeof(BITSTREAM));
bs->fp = fopen(filename "rb");
/* etc */
return bs;
}
void destroybitstream(BITSTREAM *bs)
{
if(bs)
{
if(bs->fp)
fclose(bs->fp);
free(bs);
}
}
In einem Fall malloc und frei Spiel, in den andere die zugewiesenen Speicher zurückgeführt werden, gibt es auch sekundäre Ressourcen und den Konstruktor und Destruktor Match In beiden Fällen sollte die malloc und die freie entspricht. Es sollte selten sein, eine Speicherregion zuzuweisen, aber nicht, wofür sie verwendet wird. Und Sie sollten nicht Zuteilungen interleaving und chaotisch freigibt.
Moderne C++ strafft dies mit eindeutigen Zeigern, die das Objekt "besitzen". Während Sie einen eindeutigen Zeiger auf Void haben können, wäre es sehr selten.
- 1. Ist es in Ordnung, downcast?
- 2. Ist es möglich, Speicher teilweise freizugeben?
- 3. Lasten von if's, ist es in Ordnung?
- 4. Ist es in Ordnung, C++ anzupassen?
- 5. Ist es in Ordnung, mit() zu verwenden?
- 6. Ist es möglich, eine Variable in C# freizugeben?
- 7. Ist es in Ordnung setContentView() einmal in onResume()
- 8. Ist das mehrdeutig oder ist es völlig in Ordnung?
- 9. Ist es in Ordnung, einen Durchgang vom Hauptfaden durchzuführen?
- 10. Ist es in Ordnung, einen Std :: Bad_alloc manuell zu werfen?
- 11. Ist es in Ordnung, eine öffentliche Variable in C# zu verwenden, wenn es schreibgeschützt ist?
- 12. Ist es in Ordnung, Objekte mit std :: for_each zu mutieren?
- 13. Ist es in Ordnung, den asynchronen Methodenaufruf nicht abzuwarten?
- 14. In Qt (4.6), ist es in Ordnung, Schlitze direkt anzurufen?
- 15. Ist es in Ordnung, "using std :: swap;" in einem Header?
- 16. Ist es in Ordnung, divs in einer Tabellenzelle zu verschachteln?
- 17. Ist es in Ordnung, UITableViewCells in einem Array zu speichern?
- 18. Ist es in Ordnung, Rendering in React zu delegieren?
- 19. Ist es in Ordnung, widersprüchliche Einschränkungen in Xcode zu ignorieren?
- 20. Ist es in Ordnung, einige IDs in HTML zu zeigen?
- 21. Ist es in Ordnung HTML in HTML-Attribute zu setzen?
- 22. Ist es in Ordnung, Junit Assert API in Java-Produktionscode
- 23. Ist es in Ordnung, eine Funktion in der Konstruktorinitialisierungsliste aufzurufen?
- 24. ist es in Ordnung, Vektor in einem Destruktor zu löschen
- 25. Ist es in Ordnung, Ereignisse von Dispose() auszulösen?
- 26. Ist 'void (*) (int)' dasselbe mit 'void (^) (int)'?
- 27. Ist TCP garantiert in Ordnung?
- 28. Ist dies eine gute Möglichkeit, Speicher in C freizugeben?
- 29. Ist es in Ordnung, HTML-Elementen eigene Attribute hinzuzufügen?
- 30. Ist es in Ordnung, AWT mit JavaFx zu verwenden?
Ist das überhaupt gültig C? Sollte das nicht die Größe von (struct foo) sein?:) –
Nicht nur ist es OK zu 'free()' ein 'void *' Wert, per Definition, alle 'free()' sieht immer ist ein 'void *', also technisch ist alles befreit in C 'void * ': –
@Daniel - Wenn du mich fragst, sollte es' struct foo * p = malloc (sizeof * p)) sein; 'aber was weiß ich? –