2017-09-07 1 views
1

ausplanen Während diese article lesen, ich kam in diesem Absatz:Mit freiem einem nicht char Zeiger in C

Zeiger auf Objekte die gleiche Größe, aber verschiedene Formate haben. Diese wird durch den Code unten dargestellt:

int *p = (int *) malloc(...); ... free(p); 

Dieser Code kann in Architekturen zu Fehlfunktionen in dem int * und char * haben unterschiedliche Darstellungen, weil kostenlos einen Zeiger der letzteren Art erwartet.

Und das ist nicht das erste Mal, dass ich gelesen, dass free erwartet einen char* Typen.

Meine Frage ist, wie zu befreien?

+2

'free' nimmt ein' void * ', kein' char * '. Holen Sie sich ein neues Buch (d. H. Nicht älter als 18 Jahre und über moderne C). Das erklärt auch die Semantik und nicht das Ergebnis von "malloc" & friends. – Olaf

+3

Aber ['frei'] (http: //en.cppreference.com/w/c/memory/free) erwartet ein 'void *' als Argument. Der Artikel, auf den Sie verlinken, ist * sehr * alt. Auch die Wahrscheinlichkeit, dass Sie jemals ein System finden, in dem verschiedene Zeigertypen unterschiedliche Darstellungen haben, ist gering bis nichts (außer Sie wollen sich auf antike Systeme und Computerarchäologie spezialisieren) –

+0

@Someprogrammerdude sogar, dass der Artikel alt ist, sind sich die Autoren bewusst der Standard C. Also ich denke, der Absatz ist falsch und nicht alt. –

Antwort

4

HINWEIS: You should not cast the return value of malloc in C.

Diese Frage veranschaulicht die Gefahren beim Lesen potenziell ungültiger Ressourcen. Es ist extrem wichtig, um sicherzustellen, dass die Ressource, die Sie lesen, genau ist! OPs Ressource in Frage, ist nicht falsch für seine Ära, aber ist gut out-of-date und folglich ist ungültig. K & R 2E ist ironisch ein Jahr älter, aber ist immer noch sehr viel in Datum (und damit immer noch sehr zu empfehlen), weil es dem Standard folgt.

void free(void *ptr); 

... und für das, was es wert ist, here's the malloc manual showing that malloc returns void *:

sein von void * Typ

Wenn wir a more reputable resource (the free manual) konsultieren, können wir sehen, dass free der Zeiger tatsächlich erwartet

void *malloc(size_t size); 

In beiden Fällen werden, wie durch C11/6.3.2.3p1 (der C11-Standard) beschrieben:

Ein Zeiger auf oder von einem Zeiger auf jeden Objekttyp umgewandelt werden kann für ungültig zu erklären. Ein Zeiger auf einen beliebigen Objekttyp kann in einen Zeiger auf void und zurück konvertiert werden; Das Ergebnis muss mit dem ursprünglichen Zeiger verglichen werden.

int *p = malloc(...); // A conversion occurs here; `void *` as returned by malloc is converted to `int *` 
free(p);    // ... and the reverse of the conversion occurs here, to complete the cycle mentioned in C11/6.3.2.3p1 

HINWEIS (falls Sie es verpasst das erste Mal): You should not cast the return value of malloc in C. Schließlich müssen Sie es nicht übertragen, wenn Sie es an free übergeben, oder?

+0

Ich habe K & R bereits studiert, und ich bin mir der Tatsache bewusst, dass 'free' eine' void * 'nimmt, ich wollte nur sicherstellen, dass das Dokument ungenau ist, indem ich nach SO frage. –

+0

Aus dem Artikel zitiere ich: ** "Neben dem Typ void *, der im nächsten Abschnitt erwähnt wird, hat der Standard den Typ long double eingeführt." **. Wie Sie sehen können, sind ihnen ** void *** und der ** Standard ** bekannt. Es geht also nicht darum, alt zu sein. –

+1

Nun, jetzt wissen Sie ... und wie einige meiner Fragen, die von einer ähnlichen "Ich brauche Validierung" Natur sind, denke ich, dass diese Frage (falsch) geschlossen und später gelöscht wird. Lass es mich wissen, wenn es ist, denn diese Frage sollte bleiben. Ja, der Artikel erwähnt den Standard und K & R2E, behauptet aber immer noch, dass Portabilität vor diesen Ressourcen notwendig ist ... Damals war das der Fall, aber nicht jetzt, vor allem für "Unix-ähnliche Betriebssysteme" (welche POSIX/the Open Gruppe definiert). – Sebivor