Frage

Betrachten Sie den folgenden Code ein:

#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;
}

Von Interesse ist hier &myAry[numStrs]: numStrs ist gleich 5, so &myAry[numStrs] zeigt auf etwas, das nicht existiert; das sechste Element im Array. Es ist ein weiteres Beispiel dafür in dem obigen Code: myVec.end(), das deutet auf eine past the-Ende des Vektors myVec. Es ist perfecly Recht die Adresse dieses Elements zu nehmen, die nicht existieren. Wir wissen, dass die Größe von string, so dass wir wissen, wo die Adresse des sechsten Elements einer C-Stil Reihe von strings zu verweisen. Solange wir diesen Zeiger nur bewerten und nie dereferenzieren, wir sind in Ordnung. Wir können es sogar auf andere Zeiger auf Gleichheit vergleichen. Die STL tut dies die ganze Zeit in Algorithmen, die auf einer Reihe von Iteratoren handeln. Die end() Iterator Punkte hinter dem Ende, und die Schlaufen halten Schleife während eines Zählers != end().

Sehen Sie also jetzt so aus:

#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;
}

Ist dieser Code legal und gut definiert? Es ist legal und gut definiert, um die Adresse eines Array-Elements über das Ende zu nehmen, wie in &myAry[numStrs], so sollte es legal und gut definiert sein, dass myPtr so zu tun, ist auch ein Array?

War es hilfreich?

Lösung

Es ist zulässig und nicht UB einen Zeiger zu haben, auf „eine über das Ende“ eines Arrays und einem einzelnen Objekt können behandelt werden, als ob es in einem Feld der Länge 1 waren; Sie müssen jedoch ptr + 1 stattdessen aufgrund der Technisierung von &ptr[1] dereferencing und dann unter der Adresse verwenden. Dies gilt auch &array[size] array + size werden.

Was Sie arbeiten, wie Sie auf allen Plattformen, von denen ich weiß, aber da erwarten, wie einfach es die eindeutig richtige Form ist, sehe ich keinen Grund, das nicht zu tun, statt.

Andere Tipps

Der C ++ Standard in 5,6 / 4 "Additive Operatoren" sagt:

  

Für die Zwecke dieser Operatoren, ein Zeiger auf ein Objekt Nonarray verhält sich wie ein Zeiger auf das erste Element eines Array der Länge eines mit der Art des Objekts als seine Elementtyp.

Der C99-Standard 6.5.6 / 7 sagt im Wesentlichen gleich.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top