G
Erstmal sollte der Aufruf von strcpy so aussehen
strcpy(b, a);
// bzw
strcpy(&b[0], &a[0]);
Zweitens hat das Programm so trotzdem undefiniertes Verhalten.
Seltsam, dass dein Compiler sowas
char a[3] = "123";
frisst. Denn "123" sind eigentlich 4 Zeichen, da du noch das abschliessenden Nullzeichen bei C-Strings beachten musst, entsprechend auch bei deinem Zielpuffer. Du kannst ja mal folgendes ausprobieren
const char a[] = "123";
size_t len = sizeof(a) / sizeof(char);
Damit kannst du die Anzahl der Elemente von a bestimmen (ürigens solltest du Stringliterale immer const definieren, da das ändern solcher undefiniertes Verhalten ergibt).
Der Unterschied zwischen strcpy und memcpy ist einfach der, dass strcpy nullterminierte Strings (C-Strings) kopiert, memcpy einfach nur rohe Daten. Deshalb musst du zB bei memcpy auch die Länge angeben, bei strcpy kann die Funktion die Länge durch das abschliessende Nullzeichen selbst bestimmen.