2009-09-15 8 views
1

C++ Une autre petite question, j'ai ce code:Vector plages dans

string sa[6] = { 
     "Fort Sumter", "Manassas", "Perryville", 
     "Vicksburg", "Meridian", "Chancellorsville" }; 
    vector<string> svec(sa, sa+6); 
    for (vector<string>::iterator iter = svec.begin(); iter != svec.end(); iter++) 
    { 
      std::cout << *iter << std::endl; 
    } 

Pourquoi est-ce que quand je fais Svec (sa, sa + 7), les œuvres de code, mais il imprime une ligne vide après le dernier mot et quand je fais sa + 8 à la place il se bloque? Parce que le tableau de chaînes n'a que 6 éléments, ne devrait-il pas planter à sa + 7?

Merci.

Répondre

5

Vous avez un tableau de seulement six éléments. Lorsque vous essayez d'accéder à l'élément "septième" supposé, vous obtenez undefined comportement. Techniquement, cela signifie que tout peut arriver, mais cela ne me semble pas une explication très utile, alors regardons de plus près. Ce tableau occupe la mémoire, et lorsque vous avez accédé à l'élément au-delà de la fin, vous étiez en train de lire la valeur qui se trouvait occuper cette mémoire. C'est possible que cette adresse n'appartient pas à votre processus, mais il est probablement, et donc il est généralement sûr de lire les sizeof(string) octets qui résident dans cet espace.

Votre programme le lisait et, comme il le lisait à travers un tableau string, il traitait cette mémoire comme s'il s'agissait d'un vrai objet string. (Votre programme ne peut pas faire la différence, il ne sait pas mieux, il essaie simplement de suivre vos instructions.) Apparemment, les données qui s'y trouvaient ressemblaient assez à un vrai objet que votre programme pouvait traiter. il en a un, au moins assez longtemps pour en faire une copie dans le vector et ensuite imprimer sa valeur (vide). Cela a fonctionné cette fois-ci, mais cela ne veut pas dire que ça marchera à chaque fois.

Il n'y avait pas de telle chance avec les données dans la "huitième" position du tableau. Il ne ressemblait pas assez à un objet string valide. Un objet string contient généralement un pointeur vers les données de caractères, avec une longueur.Peut-être que la zone de l'objet qui représenterait normalement ce pointeur ne contient pas une adresse valide pour votre programme. Ou peut-être que la partie représentant le champ longueur contenait une valeur beaucoup plus grande que celle disponible à l'adresse du pointeur.

11

L'accès après la fin d'un vecteur est un comportement indéfini. Tout peut arriver. Vous pourriez avoir nasal demons.

+0

Merci pour la réponse rapide. –

5

Votre application ne plante pas car il existe une norme qui spécifie qu'elle doit tomber en panne. Crashing est juste un comportement aléatoire (indéfini). Vous n'obtiendrez pas toujours un plantage lorsque vous dépassez les limites d'un tableau, comme vous l'avez découvert. Essentiellement, tout peut arriver, comme l'impression d'une ligne vide, un écrasement ou même un simple affichage - des démons sortent de votre nez.

2

C++ ne vérifie pas la portée des tableaux.

lecture au-delà de la fin d'un tableau est ce qu'on appelle le comportement « non défini »: dire qu'il est pas garanti de lancer une exception, ce n'est pas garanti pas lancer une exception, et il est pas garanti d'avoir un comportement cohérent d'une exécution au suivant.

Si les gens disent que C++ est un langage «dangereux», cela fait partie de ce qu'ils entendent par là. C++ ne vérifie pas la plage au moment de l'exécution, parce que faire un temps d'exécution prend des instructions CPU supplémentaires, et une partie de la philosophie de conception de C++ est de ne pas le ralentir. C.

Votre compilateur a peut-être été capable de vous avertir au moment de la compilation (utilisez-vous les options de la ligne de commande du compilateur pour obtenir le plus grand nombre possible d'avertissements?), bien que cela ne soit pas garanti/requis par la langue.

Questions connexes