<?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[Exception implementierung: Speicherzugriffsfehler]]></title><description><![CDATA[<p>Hi, zurzeit versuche ich eine exception-klasse zu schreiben, die einen fehler string übergeben bekommt und diesen ausgeben kann, nebenbei sollen die implementierung-details der klasse versteckt werden. Biserher habe ich das so realisiert:</p>
<pre><code class="language-cpp">class exception {
  public:
    exception(const std::string&amp; error) throw();
    ~exception() throw();
    const std::string&amp; what() const throw();

  private:
    class exception_impl* my;
};

class exception_impl {
  public:
    const std::string error;

    exception_impl(const std::string&amp; err) :
      error(err) {
    }
    ~exception_impl() {
    }
};

exception::exception(const std::string&amp; error) throw() :
  my(new exception_impl(error)) {
}

exception::~exception() throw() {
  delete my;
}

const std::string&amp; exception::what() const throw() {
  return my-&gt;error;
}
</code></pre>
<p>Der Aufruf erfoglt dann so:</p>
<pre><code class="language-cpp">int main(int argc, char* argv[]) {
  try {
    throw exception(&quot;exceptional&quot;);
  } catch(exception e) {
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
  }

  return 0;
}
</code></pre>
<p>Doch dabei erhalte ich dann folgende ausgabe:</p>
<pre><code>exceptional
Speicherzugriffsfehler
</code></pre>
<p>Die Klasse funktioniert also wie gewünscht, bis auf der Speicherzugriffsfehler. Soweit ich herausfinden konnte hängt dieser mit dem &quot;delete my;&quot; in zeile 27 der exception-implementation zusammen, mir is jedoch nicht bewusst wie ich dies umgehen könnte, ohne ein speicherleck zu provozieren.</p>
<p>Vielen Dank für euere Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/266802/exception-implementierung-speicherzugriffsfehler</link><generator>RSS for Node</generator><lastBuildDate>Wed, 02 Sep 2026 19:55:05 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/266802.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 14 May 2010 17:07:48 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Fri, 14 May 2010 17:07:48 GMT]]></title><description><![CDATA[<p>Hi, zurzeit versuche ich eine exception-klasse zu schreiben, die einen fehler string übergeben bekommt und diesen ausgeben kann, nebenbei sollen die implementierung-details der klasse versteckt werden. Biserher habe ich das so realisiert:</p>
<pre><code class="language-cpp">class exception {
  public:
    exception(const std::string&amp; error) throw();
    ~exception() throw();
    const std::string&amp; what() const throw();

  private:
    class exception_impl* my;
};

class exception_impl {
  public:
    const std::string error;

    exception_impl(const std::string&amp; err) :
      error(err) {
    }
    ~exception_impl() {
    }
};

exception::exception(const std::string&amp; error) throw() :
  my(new exception_impl(error)) {
}

exception::~exception() throw() {
  delete my;
}

const std::string&amp; exception::what() const throw() {
  return my-&gt;error;
}
</code></pre>
<p>Der Aufruf erfoglt dann so:</p>
<pre><code class="language-cpp">int main(int argc, char* argv[]) {
  try {
    throw exception(&quot;exceptional&quot;);
  } catch(exception e) {
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
  }

  return 0;
}
</code></pre>
<p>Doch dabei erhalte ich dann folgende ausgabe:</p>
<pre><code>exceptional
Speicherzugriffsfehler
</code></pre>
<p>Die Klasse funktioniert also wie gewünscht, bis auf der Speicherzugriffsfehler. Soweit ich herausfinden konnte hängt dieser mit dem &quot;delete my;&quot; in zeile 27 der exception-implementation zusammen, mir is jedoch nicht bewusst wie ich dies umgehen könnte, ohne ein speicherleck zu provozieren.</p>
<p>Vielen Dank für euere Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897193</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897193</guid><dc:creator><![CDATA[aXyde]]></dc:creator><pubDate>Fri, 14 May 2010 17:07:48 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Fri, 14 May 2010 17:15:37 GMT]]></title><description><![CDATA[<p>Dir fehlt wohl der Kopierkonstruktor (Zuweisungsoperator wäre auch nicht schlecht).<br />
Wird die exception zerstört wird immer das my ebenfalls zerstört. du holst dir in dem catch nur ne Kopie, ich weiß nicht inwieweit bei dem throw schon kopiert wird. Jedenfalls sorgt der fehlende Kopierkonstruktor dafür dass nur der Pointer kopiert wird. Wird der zerstört versucht die Kopie weiterhin darauf zuzugreifen -&gt; Segfault.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897199</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Fri, 14 May 2010 17:15:37 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Fri, 14 May 2010 17:17:31 GMT]]></title><description><![CDATA[<p>Du hast keinen Kopierkonstruktor und Zuweisungsoperator definiert. Das Objekt wird kopiert, und jedes Mal zerstört, wobei <code>delete</code> mehrfach auf den selben Speicherbereich angewendet wird.</p>
<p>Verzichte auf <code>new</code> und benutze Wertsemantik.</p>
<pre><code class="language-cpp">exception_impl my;
</code></pre>
<p>Benötigt zwar die Definition von <code>exception_impl</code> , aber bei der Grösse ist das kein Problem. Du könntest auf diese Klasse ohnehin verzichten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897201</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897201</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 14 May 2010 17:17:31 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Fri, 14 May 2010 19:16:44 GMT]]></title><description><![CDATA[<p>noch am rande:</p>
<pre><code class="language-cpp">exception::exception(const std::string&amp; error) throw() :
  my(new exception_impl(error)) {
}
</code></pre>
<p>pfui! wenn ne exception fliegen kann(und das kann sie definitiv, weil dort 2 news sind), dann schreib das throw() doch einfach nicht hin...</p>
<p>bb</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897275</guid><dc:creator><![CDATA[unskilled]]></dc:creator><pubDate>Fri, 14 May 2010 19:16:44 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 11:21:17 GMT]]></title><description><![CDATA[<p>Nochmal eine Nachfrage...</p>
<p>Da ich meine Copy-Constructor und den operator== immer vorbildlich implementiere ^^,<br />
ist mir folgendes noch nie aufgefallen.</p>
<p>Ich meine in Erinnerung zu haben, dass man mich in meinen C++-Anfängen aufgeklärt<br />
hat, dass man (in der Regel) Objekte schmeißt, statt Zeiger darauf.<br />
Da war ich etwas verwundert, dass man sie als Referenz fängt, da diese nach<br />
meiner naiven Annahme ja auf dem Stack liegen. Jedoch hat man mir darauf gesagt,<br />
dass diese an einen sicheren Ort kopiert werden ohne (!!!) jedoch den Copy-<br />
Construktor aufzurufen.</p>
<p>Jetzt habe ich gerade den Code kopiert.</p>
<p>Ursprüngliche Ausgabe:</p>
<pre><code>exceptional
test(2819) malloc: *** error for object 0x100150: double free
*** set a breakpoint in malloc_error_break to debug
test(2819) malloc: *** error for object 0x1001e0: double free
*** set a breakpoint in malloc_error_break to debug
</code></pre>
<p>Zwei Speicherzugriffsfehler, weil ja auch der interne string doppelt freigegeben wird.</p>
<p>Das catch habe ich dann mit einer Referenz ersetzt:</p>
<pre><code class="language-cpp">try {
    throw exception(&quot;exceptional&quot;);
  } catch(const exception&amp; e) {
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
  }
</code></pre>
<p>Ausgabe:</p>
<pre><code>exceptional
</code></pre>
<p>Dann kriege ich keinen Speicherzugriffsfehler.<br />
Wenn ich jetzt eine Ausgabe im Copy-Constructor mache, dann wird sie nicht ausgegeben.</p>
<pre><code class="language-cpp">exception::exception(const exception&amp; e){
        std::cout &lt;&lt; &quot;copy&quot; &lt;&lt; std::endl;
}
</code></pre>
<pre><code>exceptional
</code></pre>
<p>Wenn ich jedoch den Copy-Constructor private mache, kompiliert das Programm nicht mehr.</p>
<pre><code class="language-cpp">private:
    exception(const exception&amp; e);
</code></pre>
<pre><code>test.cpp:26: error: ‘exception::exception(const exception&amp;)’ is private
test.cpp:44: error: within this context
test.cpp:26: error: ‘exception::exception(const exception&amp;)’ is private
test.cpp:44: error: within this context
</code></pre>
<p>Der Vollständigkeit wegen:<br />
Wenn ich in den ursprünglichen Code die Ausgabe im Copy-Constructor reinmache,<br />
erhalte ich folgendes:</p>
<pre><code>copy
Bus error
</code></pre>
<p>Was passiert nun beim Schmeissen einer Excpetion? Wird eine Kopie angelegt?<br />
Wenn ja, wie? magic oder durch Aufruf des Copy-Constructors?<br />
Wenn durch Aufruf des Copy-Constructors, wo ist meine Ausgabe? <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>Gruß,<br />
CSpille</p>
<p>EDIT: Vielleicht ist der Compiler noch interessant: i686-apple-darwin9-g++-4.0.1</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897457</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897457</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sat, 15 May 2010 11:21:17 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 12:32:41 GMT]]></title><description><![CDATA[<p>Auch wenn ich noch weiß wieso, hier steht, dass ein Copy-Constructor<br />
nötig ist, auch wenn das Objekt nicht kopiert wird:<br />
<a href="http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.1" rel="nofollow">http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.1</a></p>
<p>Es scheint mir zudem so, dass ein Objekt, das geschmissen wird, intelligenterweise<br />
(von meinem Compiler) nicht erst auf dem Stack angelegt wird, denn<br />
eine Ausgabe von this im Exception-Constructor zeigt mir folgendes:</p>
<pre><code>0xbffff9a0
0xbffff99c
0xbffff998
0xbffff994
0x100280
exceptional
</code></pre>
<p>bei dem Code:</p>
<pre><code class="language-cpp">try {
    exception ex1(&quot;test&quot;);
    exception ex2(&quot;test&quot;);
    exception ex3(&quot;test&quot;);
    exception ex4(&quot;test&quot;);
    throw exception(&quot;exceptional&quot;);
  } catch(const exception&amp; e) {
    std::cerr &lt;&lt; e.what() &lt;&lt; std::endl;
  }
</code></pre>
<p>und die Speicheradressen sind scheinbar völlig verschieden,<br />
was mich zu der Annahme führt: Keine Stack-Verwendung bei throw</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897501</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897501</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sat, 15 May 2010 12:32:41 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 12:39:35 GMT]]></title><description><![CDATA[<p>CSpille schrieb:</p>
<blockquote>
<p>Was passiert nun beim Schmeissen einer Excpetion? Wird eine Kopie angelegt?<br />
Wenn ja, wie? magic oder durch Aufruf des Copy-Constructors?<br />
Wenn durch Aufruf des Copy-Constructors, wo ist meine Ausgabe? <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>
</blockquote>
<p>Das ist wie bei <code>return</code> : Normalerweise wird das Objekt kopiert, durch Optimierungen kann eine unnötige Kopie (gerade bei namenlosen temporären Objekten) aber wegfallen. Der Kopierkonstruktor muss jedoch vorhanden sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897510</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897510</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 15 May 2010 12:39:35 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 12:53:06 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>CSpille schrieb:</p>
<blockquote>
<p>Was passiert nun beim Schmeissen einer Excpetion? Wird eine Kopie angelegt?<br />
Wenn ja, wie? magic oder durch Aufruf des Copy-Constructors?<br />
Wenn durch Aufruf des Copy-Constructors, wo ist meine Ausgabe? <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>
</blockquote>
<p>Das ist wie bei <code>return</code> : Normalerweise wird das Objekt kopiert, durch Optimierungen kann eine unnötige Kopie (gerade bei namenlosen temporären Objekten) aber wegfallen. Der Kopierkonstruktor muss jedoch vorhanden sein.</p>
</blockquote>
<p>Stimmt...<br />
Bei return kann die Kopie ja auch wegoptimiert werden...</p>
<p>Danke Nexus!!!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897520</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897520</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sat, 15 May 2010 12:53:06 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 13:14:09 GMT]]></title><description><![CDATA[<p>Für mich als Anfänger sehr intressant zu lesen CSpille! Aber was sollte man jetzt nutzen?</p>
<pre><code class="language-cpp">catch(const exception&amp; e)
</code></pre>
<p>oder</p>
<pre><code class="language-cpp">catch(excpetion e)
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1897529</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897529</guid><dc:creator><![CDATA[x4rd3n]]></dc:creator><pubDate>Sat, 15 May 2010 13:14:09 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 13:17:50 GMT]]></title><description><![CDATA[<p>Du solltest Referenzen fangen.</p>
<pre><code class="language-cpp">catch (exception&amp; e)
catch (const exception&amp; e)
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1897531</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897531</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sat, 15 May 2010 13:17:50 GMT</pubDate></item><item><title><![CDATA[Reply to Exception implementierung: Speicherzugriffsfehler on Sat, 15 May 2010 13:24:15 GMT]]></title><description><![CDATA[<p>Referenz, weil ansonsten der Kopierkonstruktor in der Funktion allenfalls selber eine Exception werfen kann und dann wird abort aufgerufen, was nicht gut ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1897536</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1897536</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sat, 15 May 2010 13:24:15 GMT</pubDate></item></channel></rss>