2012-10-28 4 views
0

Je ne comprends pas comment cela fonctionne. Dire que je donne les résultats suivants:C: Erreur d'impression étrange?

void print(char* str, int len) 
{ 
    int i = 0; 
    for (i=0; i<len; i++) 
    { 
     if (str[i]=='\0') 
      printf(" "); 
     else 
      printf("%c", str[i]); 
    } 
    printf("\n\n"); 
} 

char* sym4 = "="; 
char str2[strlen(var)+strlen(sym4)]; 

unsigned long temp1 = 0x00000008; 
unsigned char* nTableSize = (unsigned char*)&temp1; 

memcpy(str2, var, strlen(var)); 
memcpy(str2+strlen(var), sym4, 1); 
memcpy(str2+strlen(var)+1, nTableSize, 4); 

print(str2, 5); 
print(str2, 6); 

et en cours d'exécution, il donne la sortie:

var= 
var 

si évidemment quelque chose va mal (plus il est déconner le reste de mon programme vers le haut). Pourquoi nTableSize n'est-il pas correctement copié dans str2 de telle sorte que l'impression de 5 caractères entraîne une sortie différente de 6? ...

+0

'memcpy (str2 + strlen (var) +1, nTableSize, 4);' est en dehors des limites. – chris

+0

Comment ça se passe hors des limites? –

+0

C'est juste assez grand pour les caractères 'strlen (var) + 1', mais vous en copiez autant, et ensuite 4 autres. – chris

Répondre

1

En supposant que vous êtes sur une architecture little-endian comme x86 ou x86-64, la valeur 4 octets 0x0000008 est représentée en mémoire sous la forme d'octets 08 00 00 00. Vous imprimez les octets en tant que caractères et le caractère 8 est ASCII pour le caractère de retour arrière '\b'. Lorsque vous imprimez un \b sur le terminal, le pilote du terminal déplace le curseur d'un caractère vers l'arrière, mais il n'écrit rien - ce n'est que lorsque vous écrivez le caractère suivant qui le remplace le caractère était auparavant là. Ainsi, lorsque vous imprimez les 5 octets "var=\b", il affiche "var=" et place le curseur sous le signe =. Mais lorsque vous imprimez les 6 octets "var=\b ", il écrit "var=", déplace le curseur en arrière et écrase le = avec un espace, vous laissant "var ".

Si vous avez redirigé la sortie vers un fichier au lieu d'imprimer vers le terminal, l'octet 08 brut est imprimé à la place.