<?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[Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11)]]></title><description><![CDATA[<p>Der Titel ist ein bisschen nichtssagend, aber mir ist nichts besseres eingefallen. Folgender Code verdeutlicht denke ich mein Problem:</p>
<pre><code>#include &lt;string.h&gt;
#include &lt;iostream&gt;

class X final
{
public:
  explicit X(const char *const str);
  ~X();
  const char *const str;
};

X::X(const char *const str): str(&quot;&quot;)
{
    auto s = new char[strlen(str)+1];
    strcpy(s, str);
    *((char **) (&amp;this-&gt;str)) = s;
}

X::~X()
{
  delete[] str;
}

int main()
{
  X x(&quot;hello&quot;);
  std::cout &lt;&lt; x.str &lt;&lt; std::endl;
  return 0;
}
</code></pre>
<p>Davon mal abgesehen dass ich hier einen C header benutze, hat der Code (für mich) zwei Probleme:<br />
- str soll nicht aus versehen verändern werden, daher ist es als const markiert. Damit kann ich allerdings str nur noch über die Initialisierungsliste des ctors verändern.<br />
- Dies führt zum nächsten Problem: Die Klasse muss ihre Ressource wieder frei geben. Da ich nicht weiß ob der Speicher auf den der übergebene pointer zeigt irgendwann mal deleted wird will ich den Inhalt kopieren.</p>
<p>Beide Ziele kann ich erreichen indem ich str mit einem leeren string initialisiere und dann im ctor den pointer gleich wieder überschreibe, das ist aber voll hässlich.</p>
<p>Eine andere Lösung wäre, den Speicher zu kopieren bevor die Instanz erzeugt wird. Dann muss ich da aber jedes mal dran denken wenn ich die Klasse instanziieren will, deswegen mag ich diese Lösung nicht.</p>
<p>Jetzt meine Frage: Lohnt es sich überhaupt str als const zu deklarieren? Ich kann das Schlüsselwort trivialerweise mit einem cast umgehen, wie oben gezeigt (allerdings ist das Ziel nur, dass man nicht aus versehen den Pointer verändert bzw. das worauf er zeigt). Gibt es eine bessere Vorgehensweise um zu verhindern, dass Speicher aus versehen mehrmals deleted/überschrieben wird?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/328732/wie-verhindert-man-am-besten-dass-speicher-ausversehen-verändert-wird-c-11</link><generator>RSS for Node</generator><lastBuildDate>Tue, 07 Jul 2026 07:47:37 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/328732.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 24 Oct 2014 14:06:12 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:06:12 GMT]]></title><description><![CDATA[<p>Der Titel ist ein bisschen nichtssagend, aber mir ist nichts besseres eingefallen. Folgender Code verdeutlicht denke ich mein Problem:</p>
<pre><code>#include &lt;string.h&gt;
#include &lt;iostream&gt;

class X final
{
public:
  explicit X(const char *const str);
  ~X();
  const char *const str;
};

X::X(const char *const str): str(&quot;&quot;)
{
    auto s = new char[strlen(str)+1];
    strcpy(s, str);
    *((char **) (&amp;this-&gt;str)) = s;
}

X::~X()
{
  delete[] str;
}

int main()
{
  X x(&quot;hello&quot;);
  std::cout &lt;&lt; x.str &lt;&lt; std::endl;
  return 0;
}
</code></pre>
<p>Davon mal abgesehen dass ich hier einen C header benutze, hat der Code (für mich) zwei Probleme:<br />
- str soll nicht aus versehen verändern werden, daher ist es als const markiert. Damit kann ich allerdings str nur noch über die Initialisierungsliste des ctors verändern.<br />
- Dies führt zum nächsten Problem: Die Klasse muss ihre Ressource wieder frei geben. Da ich nicht weiß ob der Speicher auf den der übergebene pointer zeigt irgendwann mal deleted wird will ich den Inhalt kopieren.</p>
<p>Beide Ziele kann ich erreichen indem ich str mit einem leeren string initialisiere und dann im ctor den pointer gleich wieder überschreibe, das ist aber voll hässlich.</p>
<p>Eine andere Lösung wäre, den Speicher zu kopieren bevor die Instanz erzeugt wird. Dann muss ich da aber jedes mal dran denken wenn ich die Klasse instanziieren will, deswegen mag ich diese Lösung nicht.</p>
<p>Jetzt meine Frage: Lohnt es sich überhaupt str als const zu deklarieren? Ich kann das Schlüsselwort trivialerweise mit einem cast umgehen, wie oben gezeigt (allerdings ist das Ziel nur, dass man nicht aus versehen den Pointer verändert bzw. das worauf er zeigt). Gibt es eine bessere Vorgehensweise um zu verhindern, dass Speicher aus versehen mehrmals deleted/überschrieben wird?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423838</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423838</guid><dc:creator><![CDATA[Antoras]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:06:12 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:12:40 GMT]]></title><description><![CDATA[<p>Wenn Du mit 'aus Versehen' meinst, dass Du ihn von außerhalb der Klasse veränderst, dann mach ihn</p>
<pre><code>private
</code></pre>
<p>.<br />
Ansonsten:<br />
Warum nimmst Du nicht einen</p>
<pre><code>std::string
</code></pre>
<p>? Den kannst Du</p>
<pre><code>const
</code></pre>
<p>machen, in der Initialisierungsliste versorgen und brauchst Dich nicht um Speicherfreigabe zu kümmern ... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423840</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423840</guid><dc:creator><![CDATA[Belli]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:12:40 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:15:37 GMT]]></title><description><![CDATA[<p>Dein Code erzeugt undefiniertes verhalten, ist also schon mal nicht von der Partie.</p>
<p>Am bequemsten geht es hier mit <code>string</code> . Der kümmert sich nämlich selbst um Speicherfreigabe und die Kopie und verkürzt den Code erheblich:</p>
<pre><code>class X final
{
public:
  explicit X(const char* str) : str(str) {}

  std::string const str;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2423841</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423841</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:15:37 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:19:26 GMT]]></title><description><![CDATA[<p>Der char* war nur ein Beispiel, das kann auch ein pointer auf irgendetwas anderes sein. std::string zu benutzen bringt also nur in diesem Beispiel etwas.</p>
<p>private möchte ich die Variable nicht machen, da ich sie von außen wieder lesen können möchte.</p>
<p>Und warum erzeugt der Code undefiniertes Verhalten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423844</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423844</guid><dc:creator><![CDATA[Antoras]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:19:26 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:22:05 GMT]]></title><description><![CDATA[<p>Antoras schrieb:</p>
<blockquote>
<p>private möchte ich die Variable nicht machen, da ich sie von außen wieder lesen können möchte.</p>
</blockquote>
<p>Wenn du nicht willst, dass von außen dran rumgespielt werden kann schreib dir nen getter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423845</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423845</guid><dc:creator><![CDATA[tkausl]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:22:05 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:23:38 GMT]]></title><description><![CDATA[<p>Antoras schrieb:</p>
<blockquote>
<p>private möchte ich die Variable nicht machen, da ich sie von außen wieder lesen können möchte.</p>
</blockquote>
<pre><code class="language-cpp">public:
const XYZ&amp; GetXYZ() const {return myXYZ;}
private:
XYZ myXYZ;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2423846</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423846</guid><dc:creator><![CDATA[daddy_felix]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:23:38 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:31:17 GMT]]></title><description><![CDATA[<p>Antoras schrieb:</p>
<blockquote>
<p>Und warum erzeugt der Code undefiniertes Verhalten?</p>
</blockquote>
<p>Weil du versuchst ein <code>const</code> Objekt zu modifizieren.</p>
<blockquote>
<p>Der char* war nur ein Beispiel, das kann auch ein pointer auf irgendetwas anderes sein. std::string zu benutzen bringt also nur in diesem Beispiel etwas.</p>
</blockquote>
<p>Dann nimm eben<a href="http://en.cppreference.com/w/cpp/container/vector" rel="nofollow"> <code>std::vector</code> </a>. Auf jeden Fall etwas dass dir manuelle Speicherverwaltung abnimmt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423850</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423850</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:31:17 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:48:01 GMT]]></title><description><![CDATA[<p>Arcoth schrieb:</p>
<blockquote>
<p>Antoras schrieb:</p>
<blockquote>
<p>Und warum erzeugt der Code undefiniertes Verhalten?</p>
</blockquote>
<p>Weil du versuchst ein <code>const</code> Objekt zu modifizieren.</p>
</blockquote>
<p>Warum ist das undefiniert? Weil der Compiler Optimierungen durchführen könnte?</p>
<p>Die Lösung mit dem Getter hat den Nachteil, dass man dann immer <code>x()</code> anstelle von <code>x</code> schreiben muss. <code>std::vector</code> ist auch eine zusätzliche Indirektion, aber damit muss man wohl leben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423851</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423851</guid><dc:creator><![CDATA[Antoras]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:48:01 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 14:56:02 GMT]]></title><description><![CDATA[<p>Antoras schrieb:</p>
<blockquote>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Antoras schrieb:</p>
<blockquote>
<p>Und warum erzeugt der Code undefiniertes Verhalten?</p>
</blockquote>
<p>Weil du versuchst ein <code>const</code> Objekt zu modifizieren.</p>
</blockquote>
<p>Warum ist das undefiniert? Weil der Compiler Optimierungen durchführen könnte?</p>
</blockquote>
<p>Ja, unter anderem.</p>
<blockquote>
<p>Die Lösung mit dem Getter hat den Nachteil, dass man dann immer <code>x()</code> anstelle von <code>x</code> schreiben muss. <code>std::vector</code> ist auch eine zusätzliche Indirektion, aber damit muss man wohl leben.</p>
</blockquote>
<p>Gewöhn dich dran. Das ist die beste Lösung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423853</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423853</guid><dc:creator><![CDATA[Nathan]]></dc:creator><pubDate>Fri, 24 Oct 2014 14:56:02 GMT</pubDate></item><item><title><![CDATA[Reply to Wie verhindert man am besten dass Speicher ausversehen verändert wird? (C++11) on Fri, 24 Oct 2014 15:11:17 GMT]]></title><description><![CDATA[<p>Nathan schrieb:</p>
<blockquote>
<p>Gewöhn dich dran. Das ist die beste Lösung.</p>
</blockquote>
<p>Ok, dann mache ich das so. Danke für alle Antworten!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2423855</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2423855</guid><dc:creator><![CDATA[Antoras]]></dc:creator><pubDate>Fri, 24 Oct 2014 15:11:17 GMT</pubDate></item></channel></rss>