2015-08-21 6 views
1

petits morceaux de code:Memcpy Lisible Gamme

int main() 
{ 
    char buf[18]; 
    char buf2[18]; 
    int newlength = 16; 
    memset(buf, '0', 16); 
    for (int i = newlength; i < 18; i++) 
     buf[i] = 0x00; 

    memcpy(buf2, buf, 18); 

    return 0; 
} 

Je veux d'abord définir une partie d'un tableau à une valeur spécifique puis je voudrais remplir le reste avec 0x00. Ensuite, je voudrais le copier dans un autre tableau.

Sur MS VS2013, je reçois un avertissement en tant que plage lisible pour que buf soit entre 0 et 15. (Analyse de code pour les avertissements C/C++ C6385 Read Overrun) Pourquoi? Memcpy ignore-t-il les bits définis sur 0x00?

+1

Veuillez fournir l'avertissement. Aussi, quel compilateur? – Barry

+1

Impossible de reproduire, je ne vois aucun avertissement. S'il vous plaît dites-nous votre compilateur + version + options (ou quel que soit l'outil produit l'avertissement). http: //coliru.stacked-crooked.com/a/90211ae6e2daa5c7 –

+0

Et en passant, y a-t-il une raison valable pour laquelle vous n'utilisez pas 'std :: vector's? –

Répondre

2

Ce message de l'analyseur de code semble être basé sur le principe que le contenu de la mémoire tampon serait défini seul en tant que sortie de memset(). Il manque le point que la boucle après memset() complète cette entrée.

Si vous double-cliquez sur l'avertissement, vous pouvez obtenir une mise en surbrillance des lignes considérées pour déclencher cet avertissement.

Mais le code que vous écrivez est correct, vous n'avez donc pas à vous soucier du résultat ici. La documentation en ligne, dit « pourrait » non « volonté »:

Cet avertissement indique que l'étendue lisible de la mémoire tampon spécifiée peut être plus petit que l'indice utilisé pour lire.

Remarques complémentaires:

Au moment de ce qui se passe plus évident pour l'analyseur, il apporte toujours les mêmes avertissements abusifs:

memset(buf, '0', 16); 
    memset(buf + 16, 0x00, 2); // for replacing the loop 

Dans ce cas, l'analyseur remarque la deuxième memset(). Mais comme il n'affecte pas buf depuis son début, il s'agit d'une entrée/sortie à une opération tampon sans prendre en compte la longueur supplémentaire.

Même ce genre sur-precautiononous Code soulève l'avertissement:

memset(buf, 0x00, sizeof(buf)); // completeky initalize the buffer 
    memset(buf, '0', 16);    // overwrite just the beginning 

Ici, il semble que dès qu'une cible opération memxxx() BEGIN du tampon, la durée de cette opération est considérée comme la partie unique initialisée. Donc, oui, l'avertissement est ennuyeux, mais faites confiance à votre code. Je ne pouvais me débarrasser de l'avertissement en faisant un codage unefficient vraiment bizarre:

memset(buf, 0x00, sizeof(buf)); // 18 bytes get initalized 
    memset(buf + 1, '0', 15);   // not begin of buffer 
    buf[0] = '0';      // not a memxxx() operation 

Malheureusement, la configuration de l'analyseur ne permet pas de désactiver simplement cette règle unique, mais l'ensemble des règles de vérification de sécurité.

+0

Je peux voir que memcpy fonctionne correctement, je n'aime pas que ça me donne un avertissement. : \ Je n'aime pas "pourrait" mais je suppose que ça va faire. Merci :) – pistachiobk

+1

@pistachiobk J'ai joué un peu pour savoir comment éviter l'avertissement (voir la modification): cette règle d'avertissement est vraiment insuffisamment définie. Son seul usage est d'attirer l'attention sur les risques potentiels qui pourraient nécessiter une analyse plus approfondie. – Christophe

+1

Commutation de memcpy (buf2, buf, 18); avec std :: copy (buf, buf + 18, buf2); efface l'avertissement. Ce doit juste être un problème de memcpy/memset dans ce cas. – pistachiobk

0

semble être un bug dans l'outil compilateur/peluches (en fonction de qui vous montre l'avertissement)

-1

Vous 16 octets d'initialisation. Vous accédez à 18 octets. Il semble penser que l'accès est en train de lire, même si ce n'est pas le cas.

+0

J'initialise les deux derniers octets dans le memset suivant de boucle for. – pistachiobk

+0

Je comprends cela; c'est pourquoi je dis "il semble penser que l'accès est en train de lire". Je ne suis pas sûr pourquoi il semble penser cela. – DrPizza