2009-07-08 11 views
3

Kann jemand das folgende Verhalten zu einem relativen Neuling erklärt ...Lese Bytes direkt aus dem RAM C++

const char cInputFilenameAndPath[] = "W:\\testerfile.bin"; 
int filesize = 4584; 

char * fileinrampointer; 
fileinrampointer = (char*) malloc(filesize); 

ifstream fsInputFileStream; 
fsInputFileStream.open(cInputFilenameAndPath, fstream::in | fstream::binary); 

fsInputFileStream.read((char *)(fileinrampointer), filesize); 

for(int f=0; f<4; f++) 
{ 
    printf("%x\n", *fileinrampointer); 
    fileinrampointer++; 
} 

ich den obigen Code erwartet den ersten 4 Bytes der Datei rread ich in Erinnerung habe gerade gelesen. In der Schleife zeige ich nur das aktuelle Byte an, auf das der Zeiger zeigt, inkrementiere dann den Zeiger, der bereit ist, das nächste Byte anzuzeigen. Wenn ich den Code ausführen, erhalte ich:

ffffff94

ffffffd2

Die Werte sind korrekt, aber jeder andere Wert scheint auf eine 64 Bit aufgefüllt werden Nummer. Da ich ihn auffordere, den Wert anzuzeigen, der durch einen 'char size'-Zeiger angezeigt wird, erwartete ich Zeichengrößenergebnisse, aber jedes zweite Ergebnis wird als sehr lang ausgegeben. Wenn ich * fileinampointer zu einem vorzeichenlosen __int8 anmelde, hinterlässt es mich mit dem Wert, den ich will (ohne die führenden 1s), der das Problem löst, aber ich frage mich nur, ob irgendjemand erklären kann, was oben passiert?

+1

Warum mit einem printf die Mühe machen? Mit cout << * fileinrampointer << endl; Sie verwenden die C++ - Methode für die Ausgabe an den Bildschirm. – Burkhard

+0

Woher bekommen Sie 64 Bits? Ich sehe nur 32 Bits. –

Antwort

8

Der Ausdruck *fileinrampointer vom Typ signed char, und es zu einem signed int gefördert wird, während printf geleitet wird. Somit breitet sich das Vorzeichenbit aus. Später drucken Sie es mit %x aus, was unsigned int in hex bedeutet, was dazu führt, dass Sie alle 1en drucken (statt sie als Teil einer 2er-Komplement-Ganzzahl mit Vorzeichen zu interpretieren). Außerdem ist ffffffd2 8 Hex-Ziffern, was bedeutet, dass es sich um eine 32-Bit-Ganzzahl mit Vorzeichen handelt.

Wenn Sie fileinrampointer als unsigned char oder unsigned __int8 deklarieren, wird das Vorzeichenbit während der Heraufstufung nicht weitergegeben. Sie können es unterzeichnet und verlassen und es

printf("%x\n", static_cast<unsigned char>(*fileinrampointer)); 

ISO/IEC 9899:1999 6.5.2.2 Stimmen:

6. Wenn der Ausdruck, der die aufgerufene Funktion bezeichnet, einen Typ hat, der keinen Prototyp enthält, werden für jedes Argument Ganzzahlpromotions ausgeführt, und Argumente vom Typ float werden zu double hochgestuft. Dies nennt man die Standard-Argument-Promotion. [...]
[...]
7. Wenn der Ausdruck, der die aufgerufene Funktion bezeichnet, einen Typ hat, der einen Prototyp enthält, werden die Argumente implizit wie durch Zuweisung in die Typen der entsprechenden konvertiert Parameter, wobei der Typ jedes Parameters die unqualifizierte Version des deklarierten Typs ist. Die Ellipsenschreibweise in einem Funktionsprototypdeklarator bewirkt, dass die Konvertierung des Argumenttyps nach dem letzten deklarierten Parameter beendet wird. Die Standard-Argument-Promotions werden für nachfolgende Argumente ausgeführt.

Dies unterstützt eindeutig meine Aussage, dass dies ganzzahlige Promotion ist, und nicht printf Interpretation.

Siehe auch
ISO/IEC 9899:1999 7.15.1.1
glibc manual A.2.2.4
glibc manual 12.12.4
securecoding.cert.org

+0

Es kann hilfreich sein, spezifisch darüber zu sein, warum das Zeichen zu einem int hochgestuft wird. :) –

+0

Es ist keine Werbung, es ist _interpretation_ als int (und gerendert als hex) durch die printf Interna, aufgrund der "% x" Formatspezifizierer – xtofl

+0

Danke, ich verstehe, warum es jetzt passiert. – Columbo

1

Sie werden nicht aufgefordert, einen Wert anzuzeigen, der von einem Zeiger mit der Größe char angegeben wird. Sie werden aufgefordert, eine hexadezimale Ganzzahl (% x) mit dem Inhalt eines char-Zeigers anzuzeigen. Nicht versucht, aber sie versuchen, es Casting konnte:

printf("%x\n", (unsigned int)(*fileinrampointer)); 
+1

Int wird es nicht tun, muss unsigniert sein. –

Verwandte Themen