memcpy fügt ffff dem Anfang eines Bytes hinzu

7

Ich habe ein Array, das so ist:

%Vor%

Wenn ich memcpy verwende:

%Vor%

Und drucken Sie beide aus:

%Vor%

druckt wie:

%Vor%

aber der andere druckt

%Vor%

Was ist passiert?

    
Hock 18.08.2010, 13:46
quelle

4 Antworten

13

Ich habe Ihren Code in ein vollständiges kompilierbares Beispiel verwandelt. Ich fügte auch ein drittes Array eines 'normalen' char hinzu, das auf meiner Umgebung signiert ist.

%Vor%

Meine Ergebnisse waren, was ich erwartet hatte.

%Vor%

Wie Sie sehen können, wird das 'extra' ff nur angehängt, wenn das Array von einem signierten Char-Typ ist. Der Grund dafür ist, dass, wenn memcpy das Array von signierten char auffüllt, die Werte mit einem hohen gesetzten Bit nun negativen char -Werten entsprechen. Bei der Übergabe an printf werden die char zu int types hochgestuft, was effektiv eine Zeichenerweiterung bedeutet.

%x gibt sie in hexadezimaler Form aus, als wären sie unsigned int , aber da das Argument als int übergeben wurde, ist das Verhalten technisch undefiniert. In der Regel ist das Verhalten bei einer Zweierkomplement-Maschine das gleiche wie bei der vorzeichenlosen Konvertierung, die mod 2 ^ N-Arithmetik verwendet (wobei N die Anzahl der Wertbits in unsigned int ist). Da der Wert nur 'leicht' negativ war (von einem schmalen, vorzeichenbehafteten Typ kommend), liegt der Wert nach der Konvertierung nahe bei dem maximal möglichen unsigned int Wert, dh er hat viele führende 1 's (in binär) oder führende f in Hex.

    
Charles Bailey 18.08.2010, 14:00
quelle
4

Das Problem ist nicht memcpy (es sei denn, Ihr Char-Typ ist wirklich 32 Bit statt 8), sieht beim Drucken eher wie eine Integer-Zeichenerweiterung aus.

Vielleicht möchten Sie Ihren printf so ändern, dass er explizit die nicht signierte char-Konvertierung verwendet, dh

%Vor%

Als Vermutung ist es möglich, dass Ihr Compiler / Optimizer array (dessen Größe und Inhalt zur Kompilierungszeit bekannt sind) und array2 anders behandelt, indem er konstante Werte zuerst auf den Stack drückt und das Zeichen fälschlicherweise drückt erweiterte Werte in der zweiten.

    
Hasturkun 18.08.2010 13:55
quelle
4

Sie sollten die höheren Bits maskieren, da Ihre Zeichen beim Aufruf einer varargs-Funktion auf int size erweitert werden:

%Vor%     
unwind 18.08.2010 13:56
quelle
2

% x Format erwartet einen Integer-Typ. Versuchen Sie, Casting zu verwenden:

%Vor%

Bearbeiten: Da es neue Kommentare zu meinem Beitrag gibt, möchte ich einige Informationen hinzufügen. Bevor die printf-Funktion aufgerufen wird, erzeugt der Compiler einen Code, der die Liste der Parameter der Stapelvariablen (...) ansteuert. Der Compiler weiß nichts über PrintF-Format-Codes und schiebt Parameter nach ihrem Typ. printf sammelt Parameter aus dem Stapel gemäß Formatierungszeichenfolge. Also wird Array [i] als char übergeben und von printf als int behandelt. Daher ist es immer eine gute Idee, Casting zu machen, wenn der Parametertyp nicht exakt mit der Formatspezifikation übereinstimmt und mit printf / scanf-Funktionen arbeitet.

    
Alex F 18.08.2010 13:54
quelle

Tags und Links