2009-07-24 6 views
4

J'utilise le code ci-dessousstrncpy et en utilisant sizeof pour copier caractères maximum

char call[64] = {'\0'} /* clean buffer */ 
strncpy(call, info.called, sizeof(call)); 

J'utilise toujours le sizeof pour la destination pour la protection d'un débordement, Incase source est supérieure à la destination. De cette façon, je peux empêcher un débordement de buffer car il ne copiera que ce que la destination peut gérer.

Mais je me demande maintenant si elle va annuler la destination.

Quelques cas.

1) Si la source est supérieure. je pouvais faire ceci:

call[strlen(call) - 1] = '\0'; /* insert a null at the last element.*/ 

2) Si la source est inférieure à la destination. appel est de 64 octets, et je copie 50 octets comme c'est la taille de la source. Va-t-il automatiquement mettre le null dans l'élément 51?

Un grand merci pour toute information,

Répondre

4

Si la longueur de la source est inférieur à le nombre maximal passé en tant que troisième paramètre strncpy mettra fin à la destination, sinon - pas.

Si la source est de longueur égale ou supérieure à la destination - c'est votre problème à traiter. Faire comme vous le suggérez - appeler strlen() - ne fonctionnera pas car le tampon ne sera pas terminé par un caractère nul et vous rencontrerez un comportement indéfini.

Vous pouvez allouer un tampon plus grand:

char buffer[bufferSize + 1]; 
strncpy(buffer, source, bufferSize); 
*(buffer + bufferSize) = 0; 
4

Votre idée:

call[strlen(call) - 1] = '\0'; 

ne fonctionnerait pas, comme vous appellerez strlen() sur une chaîne non terminée

12

strncpy sera pas nul mettre fin à la destination si elle tronque la chaîne. Si vous devez utiliser strncpy, vous devez vous assurer que le résultat est mis fin, quelque chose comme:

strncpy(call, info.called, sizeof(call) - 1); 
call[sizeof(call) - 1] = '\0'; 

BSD de strlcpy(), entre autres, est généralement considéré comme supérieur:

http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy

+0

Une façon simple d'assurer que la destination est nulle est terminée ici est de faire appel [sizeof call -1] = 0; – nos

+0

Je ne pensais pas que strncpy mettrait fin à la chaîne. En ne terminant pas la chaîne. Cela pourrait-il conduire à un vrai problème? Aussi en faisant cet appel [strlen (info.called - 1] = '\ 0'; Quelle est la bonne façon de terminer si la source est supérieure ou inférieure à la destination? Merci – ant2009

+0

Oui, une chaîne non terminée provoquera ' strlen() ',' strcat() ', etc., avoir une erreur, une corruption de mémoire et/ou un plantage Le paramétrage du dernier octet du tampon à zéro ne nuit à rien quand la chaîne est plus courte que la destination, –

1

Mais je Je me demande maintenant si cela va annuler la destination.

Non, strncpy ne promet pas que la chaîne cible serait terminée par un caractère nul.

char tar[2]={0,0}; 
char bar="AB"; 
strncpy(tar,bar,2); 
// result tar[0]=='A'; tar[1]=='B' 

Il pour la rendre correcte, vous devez utiliser:

strncpy(traget,string,sizeof(target)-1); 
target[sizeof(target)-1]=0 
+0

Je me demande juste. Y at-il une réelle différence dans l'utilisation de strlen ou sizeof? – ant2009

+0

sizeof est constant, il retourne sizeof objet, quand strlen calcule réellement en runtime la longueur de la chaîne. Par exemple pour char tar [2] = {0,0}; sizeof (tar) == 2 mais, strlen (tar) == 0; – Artyom

1

1) De cplusplus.com: « Non null caractère est implicitement ajouté à la fin de destination, si la destination ne sera un caractère nul terminé si la longueur de la chaîne C dans la source est inférieure à num. " Donc, si vous avez besoin de votre chaîne à zéro terminal, vous devez faire ceci:

call[sizeof(call) - 1] = '\0'; 

Une bonne façon de le faire serait d'écrire une fonction wrapper pour strncpy qui fait toujours que la chaîne est terminée.

2) Si la source est plus courte que la destination, la destination sera terminée par un caractère nul. Utilisez simplement strlcpy() au lieu de strncpy().

0

Vous devrez vérifier si elle est disponible sur toutes les plateformes. Les premières versions de Linux ne l'ont probablement pas.

+0

Ce n'est pas une fonction standard. Ce n'est peut-être pas disponible. –

Questions connexes