2016-09-21 2 views
0

Ich möchte den Abstand zwischen einem Programm der bss Abschnitt und dem Beginn des Heap-Abschnitt berechnen, also habe ich ein Programm wie dieses bekam:Pointer arithmatic zu kompilieren fehlgeschlagen ist, sagt gcc ungültige Typumwandlung

$ cat 1.cpp

#include<unistd.h> 
#include<stdlib.h> 
#include<stdio.h> 
int empty;//bss 
int main() 
{ 
    char*p=(char*)malloc(0); 
    printf("%d\n",(int)p-(int)&empty); 
    return 0; 
} 

Wenn ich diesen Code zu kompilieren mit:

$ g++ 1.cpp 

Die Fehler sind:

1.cpp: In function ‘int main()’: 
1.cpp:8:22: error: cast from ‘char*’ to ‘int’ loses precision [-fpermissive] 
    printf("%d\n",(int)p-(int)&empty); 
       ^
1.cpp:8:30: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive] 
    printf("%d\n",(int)p-(int)&empty); 
         ^

Ich glaube nicht, es unpassend ist ein int* zu int konvertieren. Ich habe viele Beispiele dafür im Internet gefunden.

Warum wird mein Code nicht kompiliert?

+0

@ user1810087 Ihr Entfernen des C++ - Tags war falsch. OP verwendet g ++ und der Code ist C++ (es wird auch in C kompiliert, da die Sprachen ähnlich sind, aber die Frage betrifft nicht C). – 2501

Antwort

3

Vertrauen Sie nicht immer, was Sie im Internet lesen.

Vermutlich befinden Sie sich auf einer Plattform, auf der Zeiger 64-Bit und int 32-Bit sind. In diesem Fall verliert eine Konvertierung von einem Zeiger zu int Genauigkeit, und Sie kompilieren mit den richtigen Flags, um dies zu einem Fehler zu machen. Gut gemacht!

Der Typ, den Sie suchen, um einen Zeiger in einen ganzzahligen Typ zu konvertieren, ist uintptr_t. Dies wird durch den Standard definiert, der eine ausreichende Breite aufweist, um eine verlustlose Umwandlung zu ermöglichen.

+0

Auch die Annahme, dass Malloced Areas in irgendeiner Beziehung zu .bss stehen sollten, ist heutzutage generell falsch. Es kann Lücken geben, und es gibt Implementierungen, die von mmaped Bereichen weit oberhalb von BSS zuweisen. – arsv

1

Der Typ, auf den von Zeigern umgewandelt werden soll, sollte uintptr_t sein, was garantiert nicht die Genauigkeit verliert, siehe auch fixed width integer types.

Wenn Sie darauf bestehen, printf zu verwenden, dann müssen Sie den richtigen Formatierer finden, weil das nicht behoben ist. Andernfalls verwenden Sie:

std::cout << reinterpret_cast<uintptr_t>(p); 
1

können Sie p-reinterpret_cast<char*>(&empty)

wollen Aber ich sehe keinen Grund, die zwei Adressen zu berechnen Abstand zwischen. (und ist undefiniertes Verhalten wie von @mch angegeben)

+0

'% d' ist der falsche Spezifizierer, um die Differenz zwischen 2 Zeigern zu drucken. Es ist auch undefiniertes Verhalten, um den Unterschied zwischen 2 Zeigern zu berechnen, die nicht auf den gleichen Speicherblock zeigen. – mch

+0

Nun, ich benutze% d, weil das OP es verwendet, und ich sage, dass ich keinen Grund sehe, dies zu tun –

+0

Antwort bearbeitet. –

Verwandte Themen