Question

Quand j'essaie de faire des choses comme ceci:

char* prefix = "Sector_Data\\sector";
char* s_num = "0";
std::strcat(prefix, s_num);
std::strcat(prefix, "\\");

et ainsi de suite et ainsi de suite, je reçois un avertissement

warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead.

Pourquoi strcat considéré comme dangereux, et est-il un moyen de se débarrasser de cet avertissement sans utiliser strcat_s?

En outre, si la seule façon de se débarrasser de l'avertissement est d'utiliser strcat_s, comment fonctionne-t-il (syntaxe sage: apparemment, il ne prend pas deux arguments)

.
Était-ce utile?

La solution

Parce que le tampon, le préfixe, pourrait avoir moins d'espace que vous copiez en elle, ce qui provoque un dépassement de mémoire tampon. Par conséquent, un pirate pourrait passer dans une chaîne spécialement conçue qui remplace l'adresse de retour ou d'une autre mémoire critique et commencer à exécuter du code dans le contexte de votre programme.

strcat_s résout ce problème en vous obligeant à passer dans la longueur de la mémoire tampon dans laquelle vous faites une copie de la chaîne; il tronquer la chaîne si nécessaire pour faire en sorte que la mémoire tampon ne soit pas dépassé.

google strcat_s pour voir précisément comment l'utiliser.

Autres conseils

Si vous utilisez c ++, pourquoi ne pas éviter tout ce gâchis et l'utilisation std::string. Le même exemple sans aucune erreur ressemblerait à ceci:

std::string prefix = "Sector_Data\\sector";
prefix += "0";
prefix += "\\"

pas besoin de se soucier de la taille des tampons et tout ce genre de choses. Et si vous avez une API qui prend const char *, vous pouvez simplement utiliser l'élément .c_str();

some_c_api(prefix.c_str());

C'est l'une des fonctions de manipulation de chaînes en C / C ++ qui peuvent conduire à des erreurs de dépassement de tampon.

Le problème est que la fonction ne sait pas ce que la taille des tampons sont. De la documentation MSDN:

  

Le premier argument, strDestination,   doit être assez grand pour contenir la   strDestination actuelle et strSource   combiné et une fermeture « \ 0 »;   sinon, un dépassement de mémoire tampon peut se produire.

strcat_s prend un argument supplémentaire lui indiquant la taille de la mémoire tampon. Cela lui permet de valider les tailles avant de faire le concat, et éviter les dépassements. Voir http://msdn.microsoft.com/en-us/library/d45bbxx4 .aspx

Vous pouvez vous débarrasser de ces avertissements en ajoutant:

_CRT_SECURE_NO_WARNINGS

et

_SCL_SECURE_NO_WARNINGS

aux définitions de préprocesseur de votre projet.

Pour activer l'avertissement désactivé, vous pouvez le faire.

#pragma warning(disable:4996)

BTW, je recommande fortement que vous utilisez strcat_s ().

Parce qu'il n'a aucun moyen de vérifier si la chaîne de destination (préfixe) dans votre cas sera écrit passé ses limites. strcat travaille essentiellement par une boucle, la copie octet par octet de la chaîne de source dans la destination. Ses arrêts quand il voit une valeur « 0 » (par notated « \ 0 ») appelé un terminal nul. Comme C n'a pas construit dans les limites de contrôle, et la dest str est juste une place dans la mémoire, strcat continuera ad-infinidium va même si elle souffle devant la source str ou dest. str ne dispose pas d'un terminal nulle.

Les solutions ci-dessus sont la plate-forme spécifique à votre environnement Windows. Si vous voulez quelque chose de plate-forme indépendante, vous devez disputer avec strncat:

strncat(char* dest, const char* src, size_t count)

Il est une autre option lorsqu'elle est utilisée intelligemment. Vous pouvez utiliser le nombre pour spécifier le nombre maximum de caractères à copier. Pour ce faire, vous devez savoir combien d'espace est disponible dans dest. (Combien vous avez alloué - strlen (dest)) et passer en tant que nombre

Il y a deux problèmes avec strcat. Tout d'abord, vous devez faire tout votre validation en dehors de la fonction, faire un travail qui est presque identique à la fonction:

if(pDest+strlen(pDest)+strlen(pScr) < destSize)

Vous devez marcher sur toute la longueur des deux chaînes juste pour vous assurer qu'il conviendra, avant de marcher sur toute leur longueur AGAIN faire la copie. À cause de cela, de nombreux programmeurs simplement supposer qu'il s'adaptera et passer le test. Pire encore, il se peut que lorsque le code est d'abord écrit, il est garanti pour adapter, mais quand quelqu'un ajoute une autre strcat, ou modifie une taille de mémoire tampon ou ailleurs constant dans le programme, vous avez maintenant des questions.

L'autre problème est que si le chevauchement PSRC et PDST. En fonction de votre compilateur, strcat peut très bien être simple boucle qui vérifie un caractère à la fois pour un 0 à PSRC. Si PDST que 0 écrase, vous entrerez dans une boucle qui se déroulera jusqu'à ce que votre programme se bloque.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top