Die manpage sagt über memset
:
#include <string.h> void *memset(void *s, int c, size_t n)
Die Funktion
memset()
füllt die erstenn
bytes des Speicherbereichs, auf dens
zeigt, mit dem konstanten Bytec
.
Es ist offensichtlich, dass memset
nicht verwendet werden kann, um int
-Array wie folgt zu initialisieren:
int a[10];
memset(a, 1, sizeof(a));
dies liegt daran, dass int
durch 4 Bytes dargestellt wird (sagen wir) und man kann nicht den gewünschten Wert für die ganzen Zahlen im Array a
erhalten.
Ich sehe jedoch oft, dass die Programmierer memset
verwenden, um die int
-Arrayelemente auf 0
oder -1
zu setzen.
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
Nach meinem Verständnis ist die Initialisierung mit Ganzzahl 0
in Ordnung, da 0
in 1 Byte dargestellt werden kann (in diesem Zusammenhang bin ich möglicherweise falsch). Aber wie kann b
mit -1
(einem 4-Byte-Wert) initialisiert werden?
Seltsamerweise ist der Grund, warum dies mit -1
funktioniert, genau derselbe wie der Grund, warum dies mit Nullen funktioniert: In Zweierkomplement-Binärdarstellung , -1
hat 1
s in allen Bits, unabhängig von der Größe der Ganzzahl, also ausfüllen Eine Region mit Bytes, die mit allen 1
s gefüllt ist, erzeugt eine Region mit -1
-signierten int
s, long
s und short
s auf der Komplement-Hardware von zwei.
Bei Hardware, die von Zweierkomplementierung abweicht, ist das Ergebnis unterschiedlich. Die Konstante -1
integer würde in einen unsigned char
aller konvertiert, da der Standard die Konvertierungsmethode genau bestimmt. Ein Bereich von Bytes, bei dem alle Bits auf 1
gesetzt sind, wird gemäß den Regeln der Plattform als ganzzahlige Werte interpretiert. Auf Hardware mit Vorzeichen und Größe enthalten beispielsweise alle Elemente Ihres Arrays den kleinsten negativen Wert des entsprechenden Typs.
0
sind, ist ihr Wert auch 0 . Wenn jedoch alle Bits1
sind, lautet der Wert -1 .
Wenn wir int a[2]
schreiben, wird4x2Byte Speicher zugewiesen, der Zufalls-/Speicherbits enthält.
00110000 00100101 11100011 11110010 11110101 10001001 00111000 00010001
Dann schreiben wir memset(a, 0, sizeof(a))
. Nun unterscheidet memset()
nicht zwischen int
und char
. Es arbeitet byte byte. Und eine Byte-Darstellung von 0 ist 00000000
. Also bekommen wir-
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Daher werden sowohl a[0]
als auch a[1]
mit 0 initialisiert.
Nun sehen wir memset(a, -1, sizeof(a))
: Ein Byte für -1 ist 11111111
. Und wir bekommen-
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
Hier haben sowohl a[0]
als auch a[1]
den Wert -1 .
Für memset(a, 1, sizeof(a))
: 1 in einem Byte ist 00000001
-
00000001 00000001 00000001 00000001 00000001 00000001 00000001 00000001
Der Wert wird also 16843009 .