web-dev-qa-db-fra.com

Comment fonctionne strcpy_s?

Comme nous le savons tous, strcpy_s est une version de sécurité de strcpy.

Mais je me demande comment ça marche ...

voyons quelques exemples.

déclaration de strpy_s:
errno_t strcpy_s (_CHAR * _DEST, size_t _SIZE, const _CHAR * _SRC)

eg1

char dest[5];
char* src = "abcdefg";
strcpy_s(dest,5,src);

Cela retournera une affirmation.
Je pense que je peux comprendre, utilisez _SIZE pour vous assurer que nous ne pouvons pas copier plus de caractères que _SIZE

Mais .. je ne peux pas comprendre ceci:

char dest[5];
char* src = "abcdefg";
strcpy_s(dest,10,src);

nous pouvons toujours obtenir une affirmation, comment cela s'est-il passé?

ps, l'erreur était:

Debug assertion a échoué
expression: (L "La mémoire tampon est trop petite" && 0)


Dans VS2013

strcpy_s vérifie-t-il la taille de la destination dans son corps? et si c'est vrai, comment? Comment vérifier un pointeur comme _DEST?

10
Joey

Voici comment obtenir la taille d'un tableau de pile au moment de l'exécution sans le décomposer en un pointeur:

template<typename T, size_t N> 
size_t arrSize(T (&array)[N])  
{
  return N;
}

Vous l'envoyez en tant que référence de modèle et le mécanisme de modèle en déduit la taille. Donc, vous pouvez faire quelque chose comme

int myArray[10];
cout << arrSize(myArray); // will display 10

Donc, je suppose que c’est ainsi que le "__ safe" MS strcpy_s "sûr" vérifie les tailles. Sinon, si vous passez juste un pointeur, il n'y a pas de moyen standard d'obtenir la taille.

8
vsoftco

En mode DEBUG, les API Microsoft remplissent le tampon avec 0xfd afin de pouvoir détecter un débordement.

Cette fonction ne tronque pas la chaîne copiée, mais déclenche une exception!

Il est toujours difficile de spécifier la taille du tampon de destination (utilisez _countof plutôt que sizeof), surtout lorsque vous utilisez un pointeur!

J'ai plus de problèmes avec ces API "_s" qu'avec les standards !!

2
Ananké

dest ne peut contenir plus de 5 caractères, c’est pourquoi vous obtenez l’erreur. Ce n'est pas à cause de _SIZE. Si dest était char*, vous devez vous assurer de lui allouer suffisamment de mémoire pour éviter toute erreur de compilation. Mais dans votre programme, dest a une taille fixe et strcpy_s, contrairement à strcpy, vérifie la taille du tampon de destination (s'il le peut, et dans ce cas, sa taille est définie au moment de la compilation). Lire ce 

http://www.cplusplus.com/forum/beginner/118771/

strcpy_s est la version "sûre" de strcpy, elle ne vous permet pas de déborder. D'après la norme: C (2011) et ISO/IEC WDTR 24731 - strcpy_s: une variante de strcpy qui vérifie la taille du tampon de destination avant la copie. En interne, probablement strcpy_s affirme sizeof(dest)<SIZE.

1
vsoftco

MSDN indique "La fonction strcpy_s copie le contenu de l'adresse de strSource, y compris le caractère nul final, vers l'emplacement spécifié par strDestination.La chaîne de destination doit être suffisamment grande pour contenir la chaîne source et son caractère nul final} _ . Le comportement de strcpy_s n'est pas défini si les chaînes source et cible se chevauchent. "

1
santosh dhanawade