2016-07-18 14 views
2

Ich studiere für einen Test und eine der Fragen war ein System wie Valgrind für Windows zu implementieren. Meine Kommilitonen und ich waren daran interessiert, die folgende dabei:Cast void * zu int und zurück

void* ptr = malloc(size); 
int ptr_location = (int)ptr; 
free((void*) ptr_location); 

Der Grund ist leicht zu verwalten Speicher von Positionen und Größen in einer Karte, anstatt den Zeiger des Haltens selbst.

Sind diese Konvertierungen legal, und gibt es einen besseren Weg, dies zu tun?

+0

Sie müssen genaue Frage angeben. – wowofbob

+0

Die Frage –

+0

hinzugefügt @Holt die Frage, die Sie markiert haben, stammt aus dem Jahr 2011, hat sich etwas verändert? –

Antwort

2

Nicht sicher, was Sie Fragen, aber im Allgemeinen das oben genannte Beispiel ist falsch und nicht portabel wie int Größe und void * kann auf verschiedenen Plattformen abweichen.

Wenn Sie wirklich void * zu einem gewissen Typ int wollen werfen, ist es besser, intptr_t zu verwenden (oder uintptr_t), die (mindestens) haben, garantiert die gleiche Größe wie void *.

+0

intptr_t ist ein Zeiger oder eine Zahl? Als ob, wie würde ich den Typ intptr_t –

+1

@ArikRinberg verwenden, ist es eine Zahl. Eine Verwendung wäre, in Ihrem Beispiel "int" durch "intptr_t" zu ersetzen. Es ist nur ein spezieller ganzzahliger Typ zum Halten von Zeigern. – wowofbob

4

Es ist Implementierung definiert Verhalten.

Zitiert C11, Kapitel §6.3.2.3/p6,

Jeder Zeigertyp kann zu einem Integer-Typ umgewandelt werden. Außer wie zuvor spezifiziert, ist das Ergebnis implementationsdefiniert. Wenn das Ergebnis nicht im Integer-Typ dargestellt werden kann, ist das Verhalten nicht definiert. Das Ergebnis muss nicht im Bereich von Werten einer Ganzzahl sein.

Vielmehr können Sie intptr_t oder uintptr_t verwenden, die in §7.20.1.4 beschrieben sind, wie (erhältlich in <stdint.h>)

[...] Typ bezeichnet a (n) (un) signed integer type mit der Eigenschaft, dass ein beliebiger gültiger Zeiger auf void in diesen Typ konvertiert werden kann, dann zurück in Zeiger auf void, konvertiert wird und das Ergebnis gleich dem ursprünglichen Zeiger verglichen wird.