Kann 'std :: basic_string :: operator []' eine "entfernte" geschützte Seite ohne Terminator zurückgeben?

8

Also sagt operator[] nicht direkt, dass s[s.size()] das Zeichen nach s[s.size()-1] im Speicher sein muss. Es scheint so zu sein, dass dies vermieden wird.

Aber s.data() gibt an, dass s.data()+k == &s[k] und s.data() einen Zeiger zurückgeben müssen.

Wenn man den scheinbaren Standardfehler der Verwendung von & auf CharT oben und nicht std::addressof ignoriert, kann die Implementierung einen anderen CharT (z. B. einen auf einer geschützten Seite oder im ROM) für% zurückgeben. co_de% vor dem ersten Aufruf von s[s.size()] ? (Natürlich könnte es den Puffer veranlassen, auf einer schreibgeschützten Seite mit einer Null zu enden; ich spreche über eine andere Situation)

Um explizit zu sein:

Soweit ich sagen kann, wenn s.data() niemals aufgerufen wird (und der Compiler kann es beweisen), muss s.data() nicht mit dem Rest des Puffers zusammenhängend sein.

Kann s[s.size()] ändern nach einem Aufruf von std::addressof(s[s.size()]) und die Implementierung ist standardkonform (solange s.data() s.data()+k == &s[k] vor .data() ausgewertet hat, aber der Compiler ist frei, das zu erzwingen). Oder gibt es Unveränderlichkeitsanforderungen, die ich nicht sehen kann?

    
Yakk 08.12.2015, 18:44
quelle

1 Antwort

1

Seit C ++ 11 muss std :: string im zusammenhängenden Speicher gespeichert werden. Dies ist das Zitat aus dem C ++ 11 Standard (Abschnitt 24.4.1.4):

  

Die char-ähnlichen Objekte in a   basic_string   Objekt soll zusammenhängend gespeichert werden. Das heißt für jeden   basic_string   Objekt   s   , Die Identität   & amp; * (s.begin () + n) = & amp; * s.begin () + n   gilt für alle Werte von   n   so dass   0   & lt; = n & lt; s.größe ()   .

Dieses Zitat über den Rückgabewert von operator [] besagt, dass es dasselbe wie &*(s.begin()+n) (Abschnitt 21.4.5.1) zurückgibt:

  

* (beginnen () + pos)   ob   Pos & lt; Größe()   . Andernfalls wird eine Referenz auf ein Objekt vom Typ zurückgegeben   Diagramm   mit Wert   Diagramm()   , wenn das Ändern des Objekts zu undefiniertem Verhalten führt

Dann haben wir dieses Zitat auf den Rückgabewert von data () in (Abschnitt 24.4.7.1):

  

Ein Zeiger   p   so dass   p + i == & amp; operator [] (i)   für jede   ich   im   [0, Größe ()]   .

Die Daten werden also genauso zurückgegeben wie mit dem & amp; -Operator []. Und jeder Wert, den Sie mit dem Operator & amp; abrufen, sollte zusammenhängend gespeichert werden. Sie können also beide schließen einen Zeiger auf zusammenhängende Speicher zurückgeben. Daher wird kein Zeiger auf eine Abstandsseite zurückgegeben.

Beachten Sie, dass dies nur für C ++ 11 gilt. Solche Garantien wurden von der Norm nicht vor C ++ 11 gegeben.

    
Shadowwolf 08.12.2015 19:07
quelle