Question

J'ai créé une fonction comme celle-ci:

bool IsSameString(char* p1, char* p2) 
{
     return 0 == strcmp(p1, p2);
}

Le problème est que parfois, par erreur, des arguments qui ne sont pas des chaînes sont passés (ce qui signifie que p1 ou p2 ne se termine pas par un caractère nul). Ensuite, strcmp continue à comparer jusqu’à atteindre la mémoire non accessible et se bloque. Existe-t-il une version sécurisée de strcmp ? Ou puis-je savoir si p1 (et p2 ) est une chaîne ou non de manière sûre?

Était-ce utile?

La solution

Non, il n'y a pas de moyen (standard) d'indiquer si un char * pointe réellement sur une mémoire valide.

Dans votre cas, il est préférable d'utiliser std :: string plutôt que char * s pour toutes vos chaînes, avec le == opérateur. Si vous faites cela, le compilateur appliquera la sécurité de type.

EDIT: Comme indiqué dans les commentaires ci-dessous, si vous vous retrouvez parfois dans une situation où vous transmettez parfois des char * contenant éventuellement des chaînes non valides, chaînes à zéro terminal alors quelque chose est fondamentalement faux avec votre approche, donc en gros La réponse de @ janm ci-dessous.

Autres conseils

Dans certains cas, std :: strncmp a> peut résoudre votre problème:

int strncmp ( const char * str1, const char * str2, size_t num ); 

Il compare jusqu'à la num C caractères de la chaîne C str1 à ceux de la chaîne C str2.

Regardez également ce que la division nationale de la cybersécurité de la DHS aux États-Unis recommande à ce sujet:

  

Assurez-vous que les chaînes sont terminées par null avant de passer dans strcmp. Ceci peut être appliqué en plaçant toujours un \ 0 dans le dernier octet alloué du tampon.

char str1[] ="something";
char str2[] = "another thing";
/* In this case we know strings are null terminated. Pretend we don't. */
str1[sizeof(str1)-1] = '\0';
str2[sizeof(str2)-1] = '\0';
/* Now the following is safe. */
if (strcmp(str1, str2)) { /* do something */ } else { /* do something else */ }

Si vous transmettez à strcmp () des chaînes qui ne sont pas terminées par null, vous les avez déjà perdues. Le fait que vous ayez une chaîne qui n'est pas null terminée (mais devrait l'être) indique que votre code contient des problèmes plus profonds. Vous ne pouvez pas modifier strcmp () pour résoudre ce problème en toute sécurité.

Vous devriez écrire votre code pour que cela ne se produise jamais. Commencez par utiliser la classe string. Aux limites où vous prenez des données dans votre code, vous devez vous assurer de traiter les cas exceptionnels; Si vous obtenez trop de données, vous devez faire ce qu'il faut. Cela n'implique pas de courir à la fin de votre tampon. Si vous devez effectuer des E / S dans une mémoire tampon de style C, utilisez des fonctions pour lesquelles vous spécifiez la longueur de la mémoire tampon, puis détectez et gérez les cas où la mémoire tampon n’est pas assez grande à cet endroit.

Il n'y a pas de remède pour cela qui soit portable. La convention stipule qu'il existe un caractère supplémentaire contenant un caractère null qui appartient au même bloc de mémoire correctement attribué que la chaîne elle-même. Soit cette convention est suivie et tout se passe bien ou un comportement indéfini se produit.

Si vous connaissez la longueur de la chaîne que vous comparez, vous pouvez utiliser strncmp () , mais cela ne changera rien si la chaîne transmise à votre code est réellement plus courte que la chaîne que vous comparez.

vous pouvez utiliser strncmp, mais si possible, utilisez std :: string pour éviter de nombreux problèmes :)

Vous pouvez définir une limite supérieure pour le nombre de caractères à comparer à l'aide de . strncmp fonction.

Il n’ya pas de meilleure réponse à cette question car vous ne pouvez pas vérifier que le caractère * est une chaîne. La seule solution est de créer un type et de l’utiliser pour string, par exemple str :: string, ou créer le vôtre si vous voulez quelque chose de plus léger. c'est-à-dire

struct MyString
  {
  MyString() : str(0), len(0) {}
  MyString( char* x ) { len = strlen(x); str = strdup(x); }
  ⁓MyString() { if(str) free(str); }
  char* str;
  size_t len;
  };

bool IsSameString(MyString& p1, MyString& p2) 
  {
  return 0 == strcmp(p1.str, p2.str);
  }


MyString str1("test");
MyString str2("test");

if( IsSameString( str1, str2 ) {}

Vous n'écrivez pas, quelle plate-forme vous utilisez. Windows a les fonctions suivantes:

IsBadStringPtr est peut-être ce que vous recherchez si vous utilisez Windows.

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