<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[std::string und die Speicherverwaltung]]></title><description><![CDATA[<p>Hi,</p>
<p>ich frage mich gerade, wie std::string seinen Speicher organisiert.</p>
<pre><code class="language-cpp">{
   unsigned char* char_ptr = foo();
   std::string s( char_ptr, size );
}
</code></pre>
<p>Ich habe einen großen C-String von irgendwo bekommen und lege nun die std::string Variable auf dem Stack an. Was passiert dann intern? Wird der Arrayinhalt aus char_ptr auf den Stack kopiert? Das könnte unter Umständen schnell zuviel werden, legt der Speicher auf dem Heap dafür an? Oder - das Beispiel ist nicht ganz richtig - für std::string müßte dies ein <strong>const char</strong> sein. Fungiert der nur als Referenz und benutzt den Inhalt des Pointers und holt sich erst Speicher, wenn er was verändert hat?</p>
<p>Hängt denn die Integrität von s an char_ptr?</p>
<p>danke</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/224947/std-string-und-die-speicherverwaltung</link><generator>RSS for Node</generator><lastBuildDate>Fri, 02 Oct 2026 00:43:08 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/224947.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 17 Oct 2008 09:44:57 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to std::string und die Speicherverwaltung on Fri, 17 Oct 2008 09:44:57 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich frage mich gerade, wie std::string seinen Speicher organisiert.</p>
<pre><code class="language-cpp">{
   unsigned char* char_ptr = foo();
   std::string s( char_ptr, size );
}
</code></pre>
<p>Ich habe einen großen C-String von irgendwo bekommen und lege nun die std::string Variable auf dem Stack an. Was passiert dann intern? Wird der Arrayinhalt aus char_ptr auf den Stack kopiert? Das könnte unter Umständen schnell zuviel werden, legt der Speicher auf dem Heap dafür an? Oder - das Beispiel ist nicht ganz richtig - für std::string müßte dies ein <strong>const char</strong> sein. Fungiert der nur als Referenz und benutzt den Inhalt des Pointers und holt sich erst Speicher, wenn er was verändert hat?</p>
<p>Hängt denn die Integrität von s an char_ptr?</p>
<p>danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1600296</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1600296</guid><dc:creator><![CDATA[GmbH]]></dc:creator><pubDate>Fri, 17 Oct 2008 09:44:57 GMT</pubDate></item><item><title><![CDATA[Reply to std::string und die Speicherverwaltung on Fri, 17 Oct 2008 09:50:11 GMT]]></title><description><![CDATA[<p>Wie std::string seine Daten intern verwaltet ist nicht festgelegt. Du kannst aber mal in den Sourcecode deiner Stringlib schauen wenn du es genau wissen willst.<br />
Ich denke fast alle Implementationen werden den Speicher dafür auf dem Heap anlegen.<br />
Der string fungiert sicher nicht als Referenz auf dein char-Array. Er hat also seine eigene Speicherverwaltung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1600298</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1600298</guid><dc:creator><![CDATA[Braunstein]]></dc:creator><pubDate>Fri, 17 Oct 2008 09:50:11 GMT</pubDate></item><item><title><![CDATA[Reply to std::string und die Speicherverwaltung on Fri, 17 Oct 2008 10:30:13 GMT]]></title><description><![CDATA[<p>Natürlich möglich das intern mit shared strings gearbeitet wird. Also bei string1 = string2 noch nichts kopiert wird, solange keiner der beiden geändert wird. Aber das ist eben nicht im Standard definiert und so kann jeder Compilerhersteller das so handhaben wie er möchte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1600313</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1600313</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Fri, 17 Oct 2008 10:30:13 GMT</pubDate></item><item><title><![CDATA[Reply to std::string und die Speicherverwaltung on Fri, 17 Oct 2008 10:38:44 GMT]]></title><description><![CDATA[<p>Der Inhalt des C-Strings wird kopiert. Ein anschließend erfolgende Änderung dieses C-Strings wirkt sich nicht auf den std::string aus - dieses Verhalten können wir nur durch Kopieren erreichen. Intern wird der string in einem Array verwaltet, das ist zwar gegenwärtig nicht explizit festgelegt, aber<br />
1. ist es eine offensichtliche, standardkonforme und effiziente Implementierung,<br />
2. jede existierende Implementierung macht es so,<br />
3. im nächsten Standard wird es auch explizit festgelegt sein.<br />
Die Größe eines std::string-Objektes ist unabhängig von der Länge des Strings, der verwaltet wird. Offensichtlich, kann sich dieser String daher zumindest ab einer gewissen Länge nicht mehr im std::string-Objekt selbst befinden. Mithin wird für die Verwaltung dann der std::allocator genutzt, welcher selbst die new/delete-Funktionen verwendet. Der betreffende Speicherbereich ist daher der Freestore.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1600318</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1600318</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 17 Oct 2008 10:38:44 GMT</pubDate></item><item><title><![CDATA[Reply to std::string und die Speicherverwaltung on Fri, 17 Oct 2008 10:42:05 GMT]]></title><description><![CDATA[<p>Fellhuhn schrieb:</p>
<blockquote>
<p>Natürlich möglich das intern mit shared strings gearbeitet wird. Also bei string1 = string2 noch nichts kopiert wird, solange keiner der beiden geändert wird. Aber das ist eben nicht im Standard definiert und so kann jeder Compilerhersteller das so handhaben wie er möchte.</p>
</blockquote>
<p>Das trifft aber nur zu, wenn wir string-Objekte kopieren - da sich Quelle und Ziel über eine durch die Implementation definierte Schnittstelle einig sind, über die Schreibvorgänge erfolgen, kann man darüber COW realisieren. Das ist umgekehrt unmöglich, wenn die Quelle ein einfacher Zeiger ist, denn es gibt über keine Möglichkeit, Schreibvorgänge auf beliebigen Objekte zu überwachen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1600321</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1600321</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 17 Oct 2008 10:42:05 GMT</pubDate></item><item><title><![CDATA[Reply to std::string und die Speicherverwaltung on Fri, 17 Oct 2008 13:07:05 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Fellhuhn schrieb:</p>
<blockquote>
<p>Natürlich möglich das intern mit shared strings gearbeitet wird. Also bei string1 = string2 noch nichts kopiert wird, solange keiner der beiden geändert wird. Aber das ist eben nicht im Standard definiert und so kann jeder Compilerhersteller das so handhaben wie er möchte.</p>
</blockquote>
<p>Das trifft aber nur zu, wenn wir string-Objekte kopieren - da sich Quelle und Ziel über eine durch die Implementation definierte Schnittstelle einig sind, über die Schreibvorgänge erfolgen, kann man darüber COW realisieren. Das ist umgekehrt unmöglich, wenn die Quelle ein einfacher Zeiger ist, denn es gibt über keine Möglichkeit, Schreibvorgänge auf beliebigen Objekte zu überwachen.</p>
</blockquote>
<p>Nur nebenbei, weil COW im Zusammenhang mit std::string erwähnt wurde...</p>
<p>COW mit std::string ist zwar möglich, aber es zahlt sich kaum aus. Der Grund ist dass man den String an so wahnsinnig vielen Stellen kopieren müsste. Beispiel:</p>
<pre><code class="language-cpp">std::string s1 = &quot;sepp&quot;;
std::string s2 = s1; // s2 hat keine eigene kopie
std::string const&amp; s2c = s2;

char c = s2[1]; // hier muss schon kopiert werden
char c2 = s2c[1]; // sogar hier müsste man genaugenommen kopieren
s2.begin(); // hier sowieso
s2c.begin(); // hier ... nicht unbedingt, ist aber auch nicht ganz klar
</code></pre>
<p>Der Grund (einer der Gründe) warum man da überall kopieren muss/müsste ist einfach dass der Standard es dem operator [] nicht erlaubt ein Proxy-Objekt zurückzugeben, sondern hier eine Referenz verlangt. Da im Fall &quot;c = s2[1]&quot; der &quot;non-const&quot; Overload von operator [] verwendet wird bleibt dem string sowieso keine andere Wahl als zu kopieren.</p>
<p>Aber selbst wenn der const Overload von [] aufgerufen wird: C++ erlaubt ausdrücklich das wegcasten von const mit const_cast wenn sichergestellt ist dass das Objekt nicht konst konstruiert wurde. Bei std::string ist das sichergestellt - zumindest solange der std::string selbst als mutable angelegt wurde, also dürfte man ohne weiteres die über &quot;operator [] const&quot; erhaltene Referenz auf non-const casten. Und damit den String modifizieren. Im Standard steht AFAIK auch nicht dass für Referenzen auf Elemente eines std::strings diesbezüglich spezielle Regeln gelten würden, also müsste die std::string Implementierung damit rechnen.</p>
<p>---</p>
<p>Ein COW std::string ist also möglich, aber der einzige Fall wo ich Chancen sehe dass es Vorteile bringt ist wenn Strings oft rumkopiert werden ohne sonst auch nur irgendwie angefasst zu werden (OK, Grösse Abfragen ginge noch, aber praktisch alles andere würde eine Kopie erzwingen, inklusive eben dem reinen &quot;auslesen&quot; des Strings). Einige wenige Anwendungen würden davon massiv profitieren, aber im allgemeinen denke ich würde es kaum was bringen. Da erwarte ich mir z.B. von move-semantics schon viel mehr <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>---</p>
<p>std::string ist IMO eine ganz gute &quot;StringBuilder&quot; Klasse, aber als String-Klasse ein totaler Reinfall.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1600428</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1600428</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 17 Oct 2008 13:07:05 GMT</pubDate></item></channel></rss>