Betrachten Sie den folgenden Code ein:Zeichenfolge s; &s+1; Legal? UB?
#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 bis 5, so &myAry[numStrs]
Punkte auf etwas gleich ist, das nicht existiert; das sechste Element im Array. Es gibt ein anderes Beispiel dafür in dem obigen Code: myVec.end()
, der auf eins nach dem Ende des Vektors zeigt myVec
. Es ist vollkommen legal, die Adresse dieses Elements zu nehmen, das nicht existiert. Wir kennen die Größe von string
, also wissen wir, wo die Adresse des 6. Elements eines C-artigen Arrays von string
s zeigen muss. Solange wir diesen Zeiger nur auswerten und ihn niemals dereferenzieren, geht es uns gut. Wir können es sogar mit anderen Hinweisen auf Gleichheit vergleichen. Die STL macht dies die ganze Zeit in Algorithmen, die auf eine Reihe von Iteratoren einwirken. Der end()
Iterator zeigt nach dem Ende, und die Schleifen bleiben in Schleife, während ein Zähler != end()
.
Also das jetzt betrachten:
#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, die Adresse eines Array-Elements nach dem Ende zu nehmen, wie in &myAry[numStrs]
, also sollte es legal und wohldefiniert sein, so zu tun, als wäre myPtr
auch ein Array?
+1 für technische Genauigkeit. Nicht nur, dass es einfach ist, es richtig zu machen, sondern es vermeidet auch weitere Fallstricke, bei denen "Operator &" überladen ist (es ist schlecht, es zu überlasten, ja. Aber das zeigt, wie man Abhängigkeiten nur schleppt). Am besten, sich von undefiniertem Verhalten frei zu halten. –