<?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 auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen]]></title><description><![CDATA[<p>Folgende Situation:</p>
<pre><code class="language-cpp">void ExceptionFunction(int x)
{
    if (x == 5)
        throw NumberIsFiveException();
}
</code></pre>
<p>Diese Funktion wird in einer anderen Funktion aufgerufen:</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
    ExceptionFunction(number);
}
</code></pre>
<p>Es ist nicht Aufgabe der OuterFunction, die Exception abzufangen. Darum kann sich derjenige kümmern, der die OuterFunction mit dem falschen Parameter aufgerufen hat.</p>
<p>Das Problem: Was ist, wenn ich sowas hier habe?</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
	AnyObject *obj = CreateAnyObject();

	ExceptionFunction(number);

	DeleteAnyObject(obj);
}
</code></pre>
<p>Wenn jetzt die ExceptionFunction eine Exception wirft, wird obj nicht mehr gelöscht und es entsteht ein Memory Leak. Ich könnte das ganze zwar folgendermaßen umgehen:</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
	AnyObject *obj = CreateAnyObject();
	bool throwException = false;

	try
	{
		ExceptionFunction(number);
	}
	catch (NumberIsFiveException ex)
	{
		throwException = true;
	}

	DeleteAnyObject(obj);

	if (throwException)
		throw NumberIsFiveException();
}
</code></pre>
<p>Aber ich kann ja theoretisch nicht wissen, welche Exception in der ExceptionFunction geworfen wird. Also habe ich letztenlich nur die Möglichkeit, eine allgemeine Exception (std::exception oder was auch immer) zu werfen, was aber bedeutet, daß nach außen hin eben nur eine allgemeine Exception gelangt. Hätte ich diesen Mist mit dem Memory Leak nicht, wäre es mir möglich gewesen, die spezielle Exception (NumberIsFiveException) nach außen zu schicken, indem ich eben gar kein eigenes try-catch reinmache.<br />
Was kann ich dagegen also tun, wenn ich keinen Garbage Collector oder Smart Pointer oder was es da extern noch so alles gibt, habe? Wie verhindere ich ein Memory Leak und leite trotzdem die richtige Exception nach außen weiter?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/272644/exception-auf-innerer-funktion-korrekt-weiterleiten-wenn-nach-dem-wurf-noch-aufräumarbeiten-kommen</link><generator>RSS for Node</generator><lastBuildDate>Fri, 28 Aug 2026 19:19:31 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/272644.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 22 Aug 2010 12:14:01 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Exception auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen on Sun, 22 Aug 2010 12:15:49 GMT]]></title><description><![CDATA[<p>Folgende Situation:</p>
<pre><code class="language-cpp">void ExceptionFunction(int x)
{
    if (x == 5)
        throw NumberIsFiveException();
}
</code></pre>
<p>Diese Funktion wird in einer anderen Funktion aufgerufen:</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
    ExceptionFunction(number);
}
</code></pre>
<p>Es ist nicht Aufgabe der OuterFunction, die Exception abzufangen. Darum kann sich derjenige kümmern, der die OuterFunction mit dem falschen Parameter aufgerufen hat.</p>
<p>Das Problem: Was ist, wenn ich sowas hier habe?</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
	AnyObject *obj = CreateAnyObject();

	ExceptionFunction(number);

	DeleteAnyObject(obj);
}
</code></pre>
<p>Wenn jetzt die ExceptionFunction eine Exception wirft, wird obj nicht mehr gelöscht und es entsteht ein Memory Leak. Ich könnte das ganze zwar folgendermaßen umgehen:</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
	AnyObject *obj = CreateAnyObject();
	bool throwException = false;

	try
	{
		ExceptionFunction(number);
	}
	catch (NumberIsFiveException ex)
	{
		throwException = true;
	}

	DeleteAnyObject(obj);

	if (throwException)
		throw NumberIsFiveException();
}
</code></pre>
<p>Aber ich kann ja theoretisch nicht wissen, welche Exception in der ExceptionFunction geworfen wird. Also habe ich letztenlich nur die Möglichkeit, eine allgemeine Exception (std::exception oder was auch immer) zu werfen, was aber bedeutet, daß nach außen hin eben nur eine allgemeine Exception gelangt. Hätte ich diesen Mist mit dem Memory Leak nicht, wäre es mir möglich gewesen, die spezielle Exception (NumberIsFiveException) nach außen zu schicken, indem ich eben gar kein eigenes try-catch reinmache.<br />
Was kann ich dagegen also tun, wenn ich keinen Garbage Collector oder Smart Pointer oder was es da extern noch so alles gibt, habe? Wie verhindere ich ein Memory Leak und leite trotzdem die richtige Exception nach außen weiter?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1942952</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1942952</guid><dc:creator><![CDATA[NES-Spieler]]></dc:creator><pubDate>Sun, 22 Aug 2010 12:15:49 GMT</pubDate></item><item><title><![CDATA[Reply to Exception auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen on Sun, 22 Aug 2010 12:24:34 GMT]]></title><description><![CDATA[<p>Warum hast du keine Smartptr?</p>
<p>Was noch ginge, ist folgendes:</p>
<pre><code class="language-cpp">try{
// hier fliegt was
}
catch(...)
{
  // Aufräumen
  throw; // Die selbe Exc. weiter werfen.
}
</code></pre>
<p>C++ hat kein finally, da es für Aufräumarbeiten auch eigentlich Destruktoren gibt, die dann automatisch aufgerufen werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1942955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1942955</guid><dc:creator><![CDATA[Maxi]]></dc:creator><pubDate>Sun, 22 Aug 2010 12:24:34 GMT</pubDate></item><item><title><![CDATA[Reply to Exception auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen on Sun, 22 Aug 2010 12:25:24 GMT]]></title><description><![CDATA[<p>Erste Möglichkeit:</p>
<pre><code class="language-cpp">void OuterFunction(int number)
{
    AnyObject *obj = CreateAnyObject();

    try
    {
        ExceptionFunction(number);
    }
    catch(...) //fange was auch immer da fliegt
    {
        DeleteAnyObject(obj);
        throw; //werfe was auch immer du gefangen hast
    }
    DeleteAnyObject(obj);
}
</code></pre>
<p>Zweite Möglichkeit:</p>
<pre><code class="language-cpp">struct AnyObjectHolder
{
  AnyObjectHolder(AnyObject* ptr) : ptr(ptr) {}
  ~AnyObjectHolder() {DeleteAnyObject(ptr);}
  AnyObject* ptr;
};

void OuterFunction(int number)
{
    AnyObjectHolder objHolder(CreateAnyObject());

    ExceptionFunction(number);

    //der Destruktor von objHolder räumt automatisch auf, egal ob exception oder nicht
}
</code></pre>
<p>Google mal nach RAII <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1942956</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1942956</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sun, 22 Aug 2010 12:25:24 GMT</pubDate></item><item><title><![CDATA[Reply to Exception auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen on Sun, 22 Aug 2010 12:32:21 GMT]]></title><description><![CDATA[<p>NES-Spieler schrieb:</p>
<blockquote>
<p>Was kann ich dagegen also tun, wenn ich keinen Garbage Collector oder Smart Pointer oder was es da extern noch so alles gibt, habe?</p>
</blockquote>
<p>Was heißt extern? auto_ptr und im neuen Standard shared_ptr sind fester Bestandteil von C++. Genauso wie man in anderen Sprachen selbstverständlich den GC diese Arbeit machen lässt, greift man in C++ auf diese Mittel zurück. Wenn die vorhandenen SmartPointer nicht zufriedenstellend sind, baut man sich seinen eigenen spezielleren RAII Container, wie von pumuckl gezeigt.</p>
<p>Wobei die allererste Wahl in C++ für mich ist, auf dynamische Erzeugung zu verzichten (was natürlich nicht immer geht).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1942959</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1942959</guid><dc:creator><![CDATA[brotbernd]]></dc:creator><pubDate>Sun, 22 Aug 2010 12:32:21 GMT</pubDate></item><item><title><![CDATA[Reply to Exception auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen on Mon, 23 Aug 2010 21:00:38 GMT]]></title><description><![CDATA[<p>Danke. Ich nehm das mit dem</p>
<pre><code class="language-cpp">try
{
}
catch (...)
{
    // Aufräumen

    throw;
}

// Aufräumen
</code></pre>
<p>Das Objekt einfach in eine Klasse packen, wo der Destruktor sowieso automatisch aufgerufen wird, kannte ich auch, wollte es aber vermeiden, da das wirklich nur ein paar Stellen sind, wo ein bißchen GDI vorkommt. (HDC und HBITMAP in ein, zwei Funktionen.)</p>
<p>auto_ptr benutzt das delete-Schlüsselwort, um das dahinterstehende Objekt zu löschen. Deshalb hab ich als Beispiel extra eine Variable genommen, die mit speziellen Funktionen erstellt und gelöscht werden.<br />
Und mit dem neuen Standard hab ich mich noch nicht wirklich befaßt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1943581</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1943581</guid><dc:creator><![CDATA[NES-Spieler]]></dc:creator><pubDate>Mon, 23 Aug 2010 21:00:38 GMT</pubDate></item><item><title><![CDATA[Reply to Exception auf innerer Funktion korrekt weiterleiten, wenn nach dem Wurf noch Aufräumarbeiten kommen on Mon, 23 Aug 2010 23:21:52 GMT]]></title><description><![CDATA[<p>NES-Spieler schrieb:</p>
<blockquote>
<p>Das Objekt einfach in eine Klasse packen, wo der Destruktor sowieso automatisch aufgerufen wird, kannte ich auch, wollte es aber vermeiden, da das wirklich nur ein paar Stellen sind, wo ein bißchen GDI vorkommt. (HDC und HBITMAP in ein, zwei Funktionen.)</p>
</blockquote>
<p>Hab' ich mir auch immer wieder gedacht.<br />
Nach einiger Zeit und vielen sinnlos geschriebenen try-catch hab' ich dann so-gut-wie alles auf RAII umgestellt <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1943609</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1943609</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Mon, 23 Aug 2010 23:21:52 GMT</pubDate></item></channel></rss>