std::string - modifizieren über &str[0] OK?
-
21.3.4/1 schrieb:
Returns: If pos < size(), returns data()[pos]. Otherwise, if pos == size(), the const
version returns charT(). Otherwise, the behavior is undefined.und
21.3.6/3/4 schrieb:
Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first
size() elements equal the corresponding elements of the string controlled by *this. If size() is
zero, the member returns a non-null pointer that is copyable and can have zero added to it.
4 Requires: The program shall not alter any of the values stored in the character array. Nor shall the program
treat the returned value as a valid pointer value after any subsequent call to a non- const member
function of basic_string that designates the same object as this.Aber: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530
-
Ryuzaki schrieb:
drakon schrieb:
23.1.1/1 schrieb:
A sequence is a kind of container that organizes a finite set of objects, all of the same type, into a strictly
linear arrangement. The library provides three basic kinds of sequence containers: vector, list, and
deque.[...]Da wird ja indirekt sogar ein Bezug zu
std::vectorgemacht.Da steht auch list, und da liegt garantiert nichts hintereinander im Speicher.
Ich hab vorhin auch mal im Standard gesucht und keine Garantie gefunden. Und wenn ich mich recht erinnere wurde hier im Forum schonmal darauf hingewiesen, dass man sich nicht darauf verlassen kann, dass das hintereinander im Speicher liegt.Stimmt. Da habe ich vorschnell das linear falsch gedeutet.
-
Ryuzaki schrieb:
Da steht auch list, und da liegt garantiert nichts hintereinander im Speicher.
Garantiert der Standard etwa, das bei
std::listnichts hintereinander liegt?
-
daersc schrieb:
Ryuzaki schrieb:
Da steht auch list, und da liegt garantiert nichts hintereinander im Speicher.
Garantiert der Standard etwa, das bei
std::listnichts hintereinander liegt?
Ja, indirekt. Nämlich durch die complexity-bounds diverser Operationen wie splice().
-
David_pb schrieb:
21.3.4/1 schrieb:
Returns: If pos < size(), returns data()[pos]. Otherwise, if pos == size(), the const
version returns charT(). Otherwise, the behavior is undefined.und
21.3.6/3/4 schrieb:
Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first
size() elements equal the corresponding elements of the string controlled by *this. If size() is
zero, the member returns a non-null pointer that is copyable and can have zero added to it.
4 Requires: The program shall not alter any of the values stored in the character array. Nor shall the program
treat the returned value as a valid pointer value after any subsequent call to a non- const member
function of basic_string that designates the same object as this.Aber: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530
Also wenn ich das richtig verstehe, dann kann ich getrost str.data() verwenden um in einen String "reinzumalen" - mittels memcpy() oder was auch immer.
Vorausgesetzt natürlich dass der String gross genug ist.
Ob die Adresse die ich über das Iterator-Interface bekomme auch die selbe ist, ist mir ziemlich egal. Ich muss das Iterator-Interface ja nicht verwenden.
-
hustbaer schrieb:
Also wenn ich das richtig verstehe, dann kann ich getrost str.data() verwenden um in einen String "reinzumalen" - mittels memcpy() oder was auch immer.
Nein, da data einen Zeiger auf konstantes charT liefert. Spätestens bei einer COW-Implementierung dürfte es Probleme geben.
&*begin() oder &at(0) etc. sind dagegen unproblematisch.
-
Jain, in 21.3.6/4 steht ganz zu beginn: The program shall not alter any of the values stored in the character array und da operator[] auf data() basiert gilt das für diesen wohl auch.
Aufgrund http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530 funktioniert das wohl trotzdem mit allen möglichen Implementierungen von basic_string. Allerdings ist das wohl nicht durch den Standard definiert.
In C++0x gibts da glaub ich dann eine Klausel die das garantiert.

-
David_pb schrieb:
Jain, in 21.3.6/4 steht ganz zu beginn: The program shall not alter any of the values stored in the character array und da operator[] auf data() basiert gilt das für diesen wohl auch.
Aufgrund http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530 funktioniert das wohl trotzdem mit allen möglichen Implementierungen von basic_string. Allerdings ist das wohl nicht durch den Standard definiert.
In C++0x gibts da glaub ich dann eine Klausel die das garantiert.

-
Er, ja, da ich data() nie verwende, wusste ich nicht, dass es davon keine non-const Variante gibt. Const wegcasten werde ich natürlich nicht.
Ich denke ich werde einfach &at(0) bzw. &[0] verwenden.
-
daersc schrieb:
Garantiert der Standard etwa, das bei
std::listnichts hintereinander liegt?
Ja, indirekt durch die Anforderungen an die Zeitkomplexität der Operationen.
hustbaer schrieb:
Ich denke ich werde einfach &at(0) bzw. &[0] verwenden.
Blöd ist nur, wenn du (oder sonst jemand) den Code portiert und dann nicht mehr daran denkt, und plötzlich hat man merkwürdige Bugs. Vielleicht kannst du ja eine Assertion schreiben, à la
char* string_data(std::string& str) { assert(&str[str.size()-1] - &str[0] == static_cast<ptrdiff_t>(str.size()-1)); return &str[0]; }Die Subtraktion erzeugt zwar undefiniertes Verhalten, wenn die beiden Zeiger nicht im gleichen Array stehen, aber sowas dürfte meiner Ansicht nach noch eher toleriert werden (und falls nicht, hat man auch nichts verloren).
Ist nur so ein Vorschlag. Wenn du den Code nie portieren wirst und dir sicher bist, dass sich deine StdLib-Implementierung nicht ändert, ist das natürlich unnötig.
-
Ja mal sehen.
Lustigerweise funktioniert es sogar mit der COW Implementierung vom VC6.
Sogar die erzwingt bei at() und [] (und begin/end/rbegin/rend) korrekterweise dass der String eindeutig gemacht wird.