Question

Considérez le code suivant:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    string myAry[] = 
    {
        "Mary",
        "had", 
        "a",
        "Little",
        "Lamb"
    };
    const size_t numStrs = sizeof(myStr)/sizeof(myAry[0]);

    vector<string> myVec(&myAry[0], &myAry[numStrs]);

    copy( myVec.begin(), myVec.end(), ostream_iterator<string>(cout, " "));

    return 0;
}

L'intérêt est ici &myAry[numStrs]: numStrs est égal à 5, points afin &myAry[numStrs] à quelque chose qui n'existe pas; l'élément sixième dans le tableau. Il y a un autre exemple dans le code ci-dessus: myVec.end(), qui pointe vers un passé, la fin du vecteur myVec. Il est perfecly juridique de prendre l'adresse de cet élément qui n'existe pas. Nous savons que la taille de string, donc nous savons où l'adresse du 6e élément d'un tableau de type C de strings doit pointer. Tant que nous évaluons que ce pointeur et ne jamais déréférencer, nous allons bien. On peut même le comparer à d'autres indicateurs pour l'égalité. La STL fait tout le temps dans les algorithmes qui agissent sur une gamme de itérateurs. Les points de iterator end() passé la fin, et les boucles tandis qu'un tourne en boucle contre != end().

Alors maintenant, considérez ceci:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    string myStr = "Mary";
    string* myPtr = &myStr;
    vector<string> myVec2(myPtr, &myPtr[1]);

    copy( myVec2.begin(), myVec2.end(), ostream_iterator<string>(cout, " "));   

    return 0;
}

Est-ce code juridique et bien défini? Il est légal et bien défini pour prendre l'adresse d'un élément de tableau passé la fin, comme dans &myAry[numStrs], donc devrait-il être légal et bien défini de prétendre que myPtr est aussi un tableau?

Était-ce utile?

La solution

Il est légal et non UB d'avoir un pointeur vers « un passé la fin » d'un tableau et un objet unique peut être traitée comme si elle était dans un tableau de longueur 1; Cependant, vous devez utiliser ptr + 1 à la place en raison de la technicité de &ptr[1] déréférencement puis prendre l'adresse. Cela vaut aussi pour devenir &array[size] array + size.

Qu'est-ce que vous avez fonctionnera comme prévu sur toutes les plateformes dont je suis au courant, mais étant donné la façon dont il est facile d'utiliser la forme correcte sans ambiguïté, je ne vois aucune raison de ne pas le faire à la place.

Autres conseils

Le C ++ standard 5.6 / 4 "opérateurs additif" dit:

  

Pour l'application de ces opérateurs, un pointeur vers un objet nonarray se comporte comme un pointeur vers le premier élément d'un tableau de longueur avec le type de l'objet comme type d'élément.

La norme C99 6.5.6 / 7 dit essentiellement la même.

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