<?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[Heap und Stack]]></title><description><![CDATA[<p>Ich habe nur eine Frage zum Heap &amp; Stack Thema, zu dem ich nirgends eine klare Antwort finden kann.</p>
<p>Neulich sagte mir der Architekt in meine Firma, ich solle nicht so viele Objekte mit den new-Operator erzeugen. Dem habe ich erstmal Folge geleistet, aber mich jetzt im Nachhinein doch mal etwas mehr damit beschäftigt, was - wie ich finde - längst überfällig war <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Wie dem auch sei, gelernt habe ich das übliche, was es zu Heap und Stack zu sagen gibt. Vor allem sowas wie &quot;Große Objekte auf dem Heap erzeugen&quot;, &quot;Heapspeicher ist größer, Stack kleiner, ..&quot; hat dann zu meiner eigentlichen Frage geführt.</p>
<p>Also doch sollte ich doch mehr auf den Heap packen? Was denn nun? Hat der Architekt recht oder nicht?</p>
<p>Bei uns besteht die Software aus vielen Modulen, also .. naja .. Paketen aus Klassen, die alle zusammen einen bestimmten Zweck verfolgen. Meist gibt es pro Modul nur eine Klasse, die das Zusammenspiel aller anderen Klassen steuert und dazu die Objekte erzeugt. Diese Instanzen werden bei Programmstart in der Main mit new erzeugt.</p>
<p>So, jetzt also endgültig zu meiner Frage: Landet alles automatisch mit auf dem Heap, was innerhalb einer Klasse erzeugt wird, wenn ich diese Klasse mit new instanziiere? (Egal ob ich dann in meinen Klassen innerhalb dieser &quot;großen Klasse&quot; noch new verwende oder nicht)?</p>
<p>Das würde für die Aussage des Softwarearchitekten sprechen, da es dann ja nicht mehr &quot;nötig&quot; ist, sich um Heap &amp; Stack gedanken zu machen, da eh alles im Heap landet und ich mir sonst nur zusätzliche Probleme mit vergessenem nicht freigegebenen Speicher einhandle, wenn ich zu viel mit new herum hantiere.</p>
<p>Ist das so korrekt?</p>
<p>Danke &amp; viele Grüße</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/333235/heap-und-stack</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Apr 2026 05:34:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/333235.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 20 Jun 2015 07:58:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 07:58:36 GMT]]></title><description><![CDATA[<p>Ich habe nur eine Frage zum Heap &amp; Stack Thema, zu dem ich nirgends eine klare Antwort finden kann.</p>
<p>Neulich sagte mir der Architekt in meine Firma, ich solle nicht so viele Objekte mit den new-Operator erzeugen. Dem habe ich erstmal Folge geleistet, aber mich jetzt im Nachhinein doch mal etwas mehr damit beschäftigt, was - wie ich finde - längst überfällig war <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<p>Wie dem auch sei, gelernt habe ich das übliche, was es zu Heap und Stack zu sagen gibt. Vor allem sowas wie &quot;Große Objekte auf dem Heap erzeugen&quot;, &quot;Heapspeicher ist größer, Stack kleiner, ..&quot; hat dann zu meiner eigentlichen Frage geführt.</p>
<p>Also doch sollte ich doch mehr auf den Heap packen? Was denn nun? Hat der Architekt recht oder nicht?</p>
<p>Bei uns besteht die Software aus vielen Modulen, also .. naja .. Paketen aus Klassen, die alle zusammen einen bestimmten Zweck verfolgen. Meist gibt es pro Modul nur eine Klasse, die das Zusammenspiel aller anderen Klassen steuert und dazu die Objekte erzeugt. Diese Instanzen werden bei Programmstart in der Main mit new erzeugt.</p>
<p>So, jetzt also endgültig zu meiner Frage: Landet alles automatisch mit auf dem Heap, was innerhalb einer Klasse erzeugt wird, wenn ich diese Klasse mit new instanziiere? (Egal ob ich dann in meinen Klassen innerhalb dieser &quot;großen Klasse&quot; noch new verwende oder nicht)?</p>
<p>Das würde für die Aussage des Softwarearchitekten sprechen, da es dann ja nicht mehr &quot;nötig&quot; ist, sich um Heap &amp; Stack gedanken zu machen, da eh alles im Heap landet und ich mir sonst nur zusätzliche Probleme mit vergessenem nicht freigegebenen Speicher einhandle, wenn ich zu viel mit new herum hantiere.</p>
<p>Ist das so korrekt?</p>
<p>Danke &amp; viele Grüße</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457281</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457281</guid><dc:creator><![CDATA[cole-hawk]]></dc:creator><pubDate>Sat, 20 Jun 2015 07:58:36 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 08:45:14 GMT]]></title><description><![CDATA[<p>Ja (innerhalb der Klsse=Membervariablen)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457285</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457285</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Sat, 20 Jun 2015 08:45:14 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 08:56:55 GMT]]></title><description><![CDATA[<p>Genau das meinte ich. Membervariablen. Die aber auch wieder vom Typ komplexer, großer Klassen mit vielen Membervariablen sein können.</p>
<p>Also ist das so. Top. Danke dir.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457286</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457286</guid><dc:creator><![CDATA[cole-hawk]]></dc:creator><pubDate>Sat, 20 Jun 2015 08:56:55 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 08:58:51 GMT]]></title><description><![CDATA[<p>Dein Meister ist dir weit voraus. Der Ratschlag an jemanden auf deinen Kenntnisstand sollte wohl eher sogar noch radikaler sein: Benutze niemals new!</p>
<p>Du machst den Fehler, anzunehmen, dass new die einzige Methode wäre, Objekte auf den Heap zu legen. Es ist eine der mit Abstand schlechtesten schlechteste von vielen.</p>
<p>Fangen wir an:<br />
1. Es sollte im schlimmsten Fall höchstens eine einzige Stelle kümmern, wo ein Objekt wirklich liegt. Wenn deine Matrixklasse anfängt, dynamischen Speicher zu verwalten, dann sind die Zuständigkeiten falsch eingeteilt. Das ist nicht ihre Aufgabe.<br />
2. Folge aus 1: Es bietet sich daher an, spezielle Ressourcenhalterklassen zu schreiben. Objekte dieser Klasse können dann dafür zuständig sein, ein anderes Objekt auf dem Heap zu verwalten. Die Klasse, der das verwaltete Objekt logisch zugehört, besitzt dann stattdessen das Objekt der Ressourcenhalterklasse. Weder die besitzende Klasse noch die verwaltete Klasse scheren sich irgendwie darum,was der Ressourcenhalter intern macht. Dank der deterministischen Konstruktoren und Destruktoren in C++ sind solche Klassen extrem elegant schreibbar. Dieses <strong>extrem wichtige</strong> Prinzip nennt sich <a href="https://en.wikipedia.org/wiki/RAII" rel="nofollow">RAII</a>.<br />
3. Diese Klassen aus 2. können eventuell effektiv intern new benutzen. Falls du selber mal solch eine Klasse schreibst, wäre hier der eine Fall, wo du mal ein tatsächlich ein new einsetzt. Aber vermutlich nicht einmal das, denn eleganter ist es, auch die Art der Ressourcenbeschaffung und Freigabe zu abstrahieren. Die Ressourcenhalterklasse ist dann ganz allgemein ein Ding, das irgendeine Funktion zur Beschaffung der Ressource aufruft und am Ende der Lebenszeit eine andere Funktion zum freigeben. Diese Funktionen können per default new und delete sein (besser: std::allocator, welcher dann in den meisten Fällen letztlich auf ein new hinaus läuft), können aber vom Nutzer auch geändert werden.<br />
4. Das haben natürlich schon viele Leute tausendfach gemacht. Daher sind solche Klassen Teil der Standardbibliothek. Es kann aber durchaus eine gute Übung sein, das einmal selber zu machen.<br />
5. In der Standardbibliothek gibt es sehr viele unterschiedliche Klassen, für viele verschiedene Anwendungsfälle. Verwaltung von einzelnen Objekte. Verwaltung von unitialisiertem Speicher. Objekte, die mehrere Eigentümer haben können. Und vieles mehr:<br />
<a href="http://en.cppreference.com/w/cpp/memory" rel="nofollow">http://en.cppreference.com/w/cpp/memory</a><br />
6. Selbst das ist meistens noch sehr konkret. Sehr oft will man die verwalteten Objekte schließlich noch zu logischen Strukturen zusammen fassen. Die gängigsten logischen Strukturen gibt es auch schon fertig:<br />
<a href="http://en.cppreference.com/w/cpp/container" rel="nofollow">http://en.cppreference.com/w/cpp/container</a></p>
<p>Die Container aus 6. sind es, mit denen du fast immer arbeitest. Das ist, was dein Kollege meint. Falls diese mal ausnahmsweise nicht ausreichen (und es keine fertige Bibliothek mit einer Lösung gibt) und du mal selber solch einen Container schreiben musst, dann wirst du meisten mit den Klassen aus 5. auskommen, um die Ressourcen des Containers zu verwalten. Und da diese derart allgemein sind, dass man damit praktisch alles machen kann (zum Beispiel ist es ein netter Trick, Unix-Pipes von einem unique_ptr verwalten zu lassen, was überhaupt gar nichts mehr mit Speichermanagement zu tun hat), wirst du vermutlich nie in die Verlegenheit kommen, einen eigenen Smartpointer zu schreiben. Und somit wirst du vermutlich auch niemals ein explizites new brauchen (und wie schon erklärt, würde selbst der Smartpointer intern nicht direkt new benutzen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457287</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457287</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sat, 20 Jun 2015 08:58:51 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 11:08:20 GMT]]></title><description><![CDATA[<p>Hallo. Danke auch für deine Antwort.</p>
<p>Im Prinzip arbeite ich schon sehr viel mit Containern. Mein Problem bei den ganzen Standard-Konstrukten wie den stl-containern ist, dass sie mitunter so einfach zu benutzen sind, dass man sich (ich mir) keine Gedanken mehr darüber machen muss, was intern eigentlich passiert. Das ist theoretisch der große Vorteil. Mir ist es jetzt aber scheinbar zum Verhängnis geworden, da ich irgendwie das Gefühl hatte, damit zuviel &quot;Overhead&quot; zu erzeugen und mit nativeren Konstrukten wie &quot;new&quot; besser (performanter) fahre, als Sachen zu nutzen, die ihre Arbeitsweise vor mir &quot;verbergen&quot;. Das ist auch der Grund, warum ich <strong>dringend</strong> dazulernen möchte, damit mir solche &quot;Fehler&quot; in Zukunft nicht mehr zum Verhängnis werden. Daher bin ich sehr dankbar über solche Lesetipps und werde auch ein bisschen hier im Forum weiter stöbern.</p>
<p>Ich möchte aber doch nochmal kurz mein Problem vorstellen, ich wills aber jetzt nicht ausarten lassen. So wie im Beispiel sieht ungefähr meine Klasse aus. SehrGrosseKlasse wird irgendwo außerhalb von meinem &quot;Zuständigkeitsbereich&quot; mit new erzeugt und dann läuft das Teil so vor sich hin (bitte nicht über den Inhalt der main() schimpfen).</p>
<p>Die Sache sieht so aus, dass SehrGrosseKlasse viele Objekte erzeugt, unter anderem auch welche, die auf andere Member von SehrGrosseKlasse zugreifen müssen.</p>
<p>Beispiel:</p>
<pre><code>class SehrGrosseKlasse {

public:
   SehrGrosseKlasse()
   : m_ressource1(),
     m_ressource2(),
     m_ressource3(),
     m_MeineAndereKlasse_1(NULL),
     m_MeineAndereKlasse_2(NULL),
     m_MeineAndereKlasse_3(NULL),
     ...
   {
      m_MeineAndereKlasse_1 = new AndereKlasse(m_ressource1, m_ressource2, m_ressource3);
      m_MeineAndereKlasse_2 = new AndereKlasse(m_ressource1, m_ressource2, m_ressource3);
      m_MeineAndereKlasse_3 = new AndereKlasse(m_ressource1, m_ressource2, m_ressource3);
   }

   ~SehrGrosseKlasse() { // delete von meinen anderen Klassen. };

private:

Ressource m_ressource1;
Ressource m_ressource2;
Ressource m_ressource3;

AndereKlasse * m_MeineAndereKlasse_1;
AndereKlasse * m_MeineAndereKlasse_2;
AndereKlasse * m_MeineAndereKlasse_3;

};

class AndereKlasse {

public:
   AndereKlasse(Ressource &amp; ressource1, Ressource &amp; ressource2, Ressource &amp; ressource3) 
   : m_ressource1(ressource1),
     m_ressource2(ressource2),
     m_ressource3(ressource3)
   {}

private:
   Ressource &amp; m_ressource1;
   Ressource &amp; m_ressource2;
   Ressource &amp; m_ressource3;
}
};

int main()
{
   SehrGrosseKlasse * klasse = new SehrGrosseKlasse();
   while(1);
}
</code></pre>
<p>Mit std::vector als Container für AndereKlasse sieht das schon eleganter aus (siehe Beispiel 2). Und wie ich gelernt habe, wird vector vermutlich den Inhalt auch auf den Heap packen und ich muss mir darum keine Gedanken machen. Worum ich mir aber bisher Gedanken gemacht habe ist die Tatsache, dass ich nun ein lokales Objekt der Klasse AndereKlasse erzeuge und push_back das irgendwohin kopiert. Wenn jetzt AndereKlasse auch groß ist und da fleißig hin und her kopiert wird, ist das doch auch nicht die beste Lösung. Was denkt ihr?</p>
<p>Alternative wäre noch Variante 1 mit SmartPointern.. m_MeineAndereKlasse_{1,2,3} direkt in der Initializerlist des Konstruktors von SehrGrosseKlasse mit den Ressourcen zu initialisieren ist sicher auch noch eine Variante (?), allerdings sieht das ganze sehr viel komplexer aus, als hier dargestellt, deshalb ist das eigentlich keine Option.</p>
<p>Beispiel 2</p>
<pre><code>class SehrGrosseKlasse {

public:
   SehrGrosseKlasse()
   : m_ressource1(),
     m_ressource2(),
     m_ressource3(),
     m_MeineAndereKlasse(),
     ...
   {
      m_MeineAndereKlasse.push_back(AndereKlasse(m_ressource1, m_ressource2, m_ressource3));
      m_MeineAndereKlasse.push_back(AndereKlasse(m_ressource1, m_ressource2, m_ressource3));
      m_MeineAndereKlasse.push_back(AndereKlasse(m_ressource1, m_ressource2, m_ressource3));
   }

private:

Ressource m_ressource1;
Ressource m_ressource2;
Ressource m_ressource3;

std::vector&lt; AndereKlasse &gt; m_MeineAndereKlasse;

};
</code></pre>
<p>Danke <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/2457299</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457299</guid><dc:creator><![CDATA[cole-hawk]]></dc:creator><pubDate>Sat, 20 Jun 2015 11:08:20 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 12:33:50 GMT]]></title><description><![CDATA[<p>cole-hawk schrieb:</p>
<blockquote>
<p>..., da ich irgendwie das Gefühl hatte, damit zuviel &quot;Overhead&quot; zu erzeugen und mit nativeren Konstrukten wie &quot;new&quot; besser (performanter) fahre, als Sachen zu nutzen, die ihre Arbeitsweise vor mir &quot;verbergen&quot;.</p>
</blockquote>
<p>Wenn du solchen Wert auf Performance legst, dann solltest du vielleicht wissen, dass <code>new</code> bzw. die meisten Varianten von <code>malloc</code> auf denen das <code>new</code> letztendlich basiert, eine relativ teure Operation sind, die höchstwahrscheinlich jeglichen eventuellen Overhead, den du z.B. durch die Verwendung eines <code>std::unique_ptr</code> / <code>std::make_unique</code> an dieser Stelle haben wirst, vollkommen dominieren werden (allerdings wage ich zu behaupten, dass die gängigen Implementierungen von <code>std::unique_ptr</code> / <code>std::make_unique</code> derart leichtgewichtig sind, dass sie überhaupt keinen Overhead im Vergleich zu einem <code>new</code> / <code>delete</code> -Paar haben).</p>
<p>Aus Performance-Betrachtungen her wäre es bei deinen Code-Beispielen daher sinnvoller zu überlegen, ob man nicht auf das eine oder andere <code>new</code> / <code>make_unique</code> komplett verzichten kann. Spricht z.B. etwas dagenen, die Instanzen von <code>AndereKlasse</code> nicht als Pointer vorzuhalten, sodern diese direkt als Member von <code>SehrGrosseKlasse</code> zu haben?:</p>
<pre><code>class SehrGrosseKlasse {
...
AndereKlasse m_MeineAndereKlasse_1;
AndereKlasse m_MeineAndereKlasse_2;
AndereKlasse m_MeineAndereKlasse_3;
};
</code></pre>
<p>Das hätte performance-technisch zwei Vorteile:</p>
<p>1. Instanzen von <code>SehrGrosseKlasse</code> können mit nur einer einzigen Speicher-Allokation erzeugt werden.</p>
<p>2. Die Member von <code>SehrGrosseKlasse</code> ( <code>m_ressource1</code> , <code>m_MeineAndereKlasse_1</code> ) liegen im Speicher direkt hintereinander, d.h. wenn du z.B. (was ich für wahrscheinlich halte) in deinem Code nacheinander auf<br />
<code>m_MeineAndereKlasse_1</code> , <code>m_MeineAndereKlasse_1</code> , etc. zugreifst, kann dein Programm so besser vom CPU-Cache profitieren - ein Effekt der ebenfalls jeglichen eventuellen (wenn überhaupt) <code>new</code> / <code>delete</code> -Performancevorteil vollkommen dominieren wird. Sich an Pointern &quot;entlangzuhangeln&quot; ist oft Gift für die Performance: Um so einen Pointer aus dem Speicher zu laden, liest so eine CPU üblicherweise eine ganze Cache-Line aus dem Speicher (bei gängigen x86/x64-CPUs sind das 64 Bytes) und benötigt letztendlich nur 4-8 Bytes davon (wenn die gelesenen 64 Bytes nicht sogar noch andere Speicherbereiche aus dem Cache verdrängen, die man im Anschluss ohnehin wieder benötigt, also dann nochmal gelesen werden müssen).</p>
<p>Generell würde ich also erst einmal immer bevorzugen, die <code>AndereKlasse</code> zu einem direkten Member von <code>SehrGrosseKlasse</code> zu machen, es sei denn du hast einen guten Grund dafür, es anders zu machen - z.B. wenn die <code>AndereKlasse</code> -Member nicht in einer 1:1-Beziehung zu <code>SehrGrosseKlasse</code> stehen. In diesem Fall machen dann eventuell <code>std::unique_ptr</code> / <code>std::shared_ptr</code> Sinn, je nachdem welche Form von &quot;Ownership&quot; gewünscht, bzw. sinnvoll ist. Allerdings kann man einer anderen Klasseninstanz durchaus auch einen <code>&amp;m_MeineAndereKlasse_1</code> -Pointer mitgeben, wenn garantiert ist (am besten durch Code-Design), dass diese nicht länger lebt als <code>SehrGrosseKlasse</code> <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>Gruss,<br />
Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457306</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457306</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sat, 20 Jun 2015 12:33:50 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 14:30:20 GMT]]></title><description><![CDATA[<blockquote>
<p>Spricht z.B. etwas dagenen, die Instanzen von AndereKlasse nicht als Pointer vorzuhalten, sodern diese direkt als Member von SehrGrosseKlasse zu haben?</p>
</blockquote>
<p>Also auf den Rat meines Kollegen hin, habe ich die Verwendung von dieser Art der Instanziierung weitestgehend reduziert und tatsächlich als Member angelegt. Da kam dann nur eben die Eingangsfrage auf, wo die ganzen Member landen (heap oder stack), wenn <code>SehrGrosseKlasse</code> per new instanziiert wird (da ich die Member ja nun nicht mehr mit new instanziiere). Aber so wie ich das verstanden habe, landet alles im Heap. Macht ja auch Sinn, hatte mich trotzdem beschäftigt.</p>
<p>Was ich aber bei meinem Beispiel vergessen habe zu erwähnen ist, das ich verschiedene Fälle habe, bei denen mir das &quot;Problem&quot; über den Weg gelaufen ist. Und einer der Gründe, der gegen das &quot;direkt als Member&quot; vorhalten spricht ist, dass das Erzeugen mitunter abhängig von Vorbedingungen ist. Das habe ich in dem Codebeispiel weggelassen.. Ganz simpel z.B. sowas in der Art:</p>
<pre><code>bool initOk = m_ressource1.init();
if ( initOk ) 
   m_MeineAndereKlasse_1 = new AndereKlasse(m_ressource1, m_ressource2, m_ressource3);
</code></pre>
<p>Wenn <code>AndereKlasse</code> etwas größer ist, was sie eben ist, dann ist es sicher kein guter Weg das Teil trotzdem zu erzeugen und dann nicht zu verwenden...</p>
<p>Würde das mit make_unique dann so aussehen?</p>
<pre><code>std::unique_ptr&lt; AndereKlasse &gt; m_MeineAndereKlasse_1;
m_MeineAndereKlasse_1 = std::make_unique&lt; AndereKlasse(m_ressource1, m_ressource2, m_ressource3) &gt;();
</code></pre>
<p>So wie ich das sehe wird hiermit auch nur wieder das new verwendet.<br />
Das heißt also für mich, mein Meister wollte mir damit sagen: &quot;new allein ist böse, da du garantiert das delete vergessen wirst.&quot;, aber nicht &quot;new und heap sind etwas böses&quot;. Letzteres war nämlich mein Gedanke bei seiner Aussage und das stand im Widerspruch mit dem, was ich bisher so über Heap &amp; Stack gelesen habe.</p>
<p>Ich nehme also mit: RAII ist etwas gutes und Smart Pointer beispielsweise setzen dieses Konzept um.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457316</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457316</guid><dc:creator><![CDATA[cole-hawk]]></dc:creator><pubDate>Sat, 20 Jun 2015 14:30:20 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 16:01:42 GMT]]></title><description><![CDATA[<p>cole-hawk schrieb:</p>
<blockquote>
<p>Würde das mit make_unique dann so aussehen?</p>
</blockquote>
<p>Nein, der Template Parameter ist nur der Name der Klasse. Außerdem bietet sich die Verwendung von auto an, dann muss man sich nicht wiederholen:</p>
<pre><code>auto m_MeineAndereKlasse_1 = std::make_unique&lt;AndereKlasse&gt;(m_ressource1, m_ressource2, m_ressource3);
</code></pre>
<p>Oder soll das Beispiel für einen Membervariable sein? Da geht das natürlich nicht mit auto.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457322</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457322</guid><dc:creator><![CDATA[sebi707]]></dc:creator><pubDate>Sat, 20 Jun 2015 16:01:42 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 17:33:20 GMT]]></title><description><![CDATA[<p>cole-hawk schrieb:</p>
<blockquote>
<pre><code>bool initOk = m_ressource1.init();
if ( initOk ) 
   m_MeineAndereKlasse_1 = new AndereKlasse(m_ressource1, m_ressource2, m_ressource3);
</code></pre>
</blockquote>
<p>Sowas ist durchaus ein guter Grund die &quot;anderen&quot; als Pointer vorzuhalten.</p>
<p>cole-hawk schrieb:</p>
<blockquote>
<p>Wenn <code>AndereKlasse</code> etwas größer ist, was sie eben ist, dann ist es sicher kein guter Weg das Teil trotzdem zu erzeugen und dann nicht zu verwenden...</p>
</blockquote>
<p>Nein. Wenn der Member auch &quot;nicht gesetzt&quot; sein kann, halte ich es auch erstmal für einen guten Weg das über einen Pointer zu lösen, der eben auch eine Repräsentation für &quot;nicht gesetzt&quot; hat ( <code>nullptr</code> ). Es kann sein, dass man sich manchmal die Datenstruktur möglichst flach halten möchte (Cache oder andere Gründe, weshalb alles möglichst kompakt im Speicher liegen sollte), und es über eine spezielle &quot;nicht gesetzt&quot;-Instanz löst, aber dafür sollte man zuerst einen wirklich triftigen Grund haben.</p>
<p>cole-hawk schrieb:</p>
<blockquote>
<p>Würde das mit make_unique dann so aussehen?</p>
</blockquote>
<p>Siehe Antwort von sebi707.</p>
<p>cole-hawk schrieb:</p>
<blockquote>
<p>So wie ich das sehe wird hiermit auch nur wieder das new verwendet.<br />
Das heißt also für mich, mein Meister wollte mir damit sagen: &quot;new allein ist böse, da du garantiert das delete vergessen wirst.&quot;, aber nicht &quot;new und heap sind etwas böses&quot;. Letzteres war nämlich mein Gedanke bei seiner Aussage und das stand im Widerspruch mit dem, was ich bisher so über Heap &amp; Stack gelesen habe.</p>
</blockquote>
<p>Nein, der Heap ist nix böses, das ist am Ende auch nur Speicher. Der Stack hat allerdings den Vorteil, dass Speicher-Allokationen dort quasi &quot;umsonst&quot; sind (Stack-Pointer hochzählen), und weil der Stack-Speicher von laufenden Programmen meisst ziemlich gut beackert wird, man bei Daten, die dort liegen wahrscheinlich eher von CPU-Cache-Effekten profitieren kann.<br />
Und ja, der vornehmliche Grund, weshalb man <code>unique_ptr</code> und Konsorten nehmen sollte ist, dass man das <code>delete</code> einfach nicht vergessen <em>kann</em>, selbst wenn die Code-Ausführung ungeahnte Wege nimmt (Exceptions et al.)... und natürlich dass man keine &quot;Dangling Pointer&quot; hat die doch irgendwie noch stillschweigend funktionieren (nach dem Reset ist das Ding einfach <code>nullptr</code> , das läuft garantiert vor die Wand).</p>
<p>cole-hawk schrieb:</p>
<blockquote>
<p>Ich nehme also mit: RAII ist etwas gutes und Smart Pointer beispielsweise setzen dieses Konzept um.</p>
</blockquote>
<p>Wenn man mich auf eine einsame Insel verbannen würde, wo ich nur in C programmieren darf, aber ich mir ein einziges Feature von C++ aussuchen kann, dann wären es wahrscheinlich Destruktoren und die schließende geschweifte Klammer <code>}</code> ... obwohl ich die anderen Features auch vermissen würde <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457325</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457325</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sat, 20 Jun 2015 17:33:20 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 21:49:00 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Der Ratschlag an jemanden auf deinen Kenntnisstand sollte wohl eher sogar noch radikaler sein: Benutze niemals new!</p>
</blockquote>
<p>new hat seine Anwendungen, wie alle anderen Sprachelemente auch. new- und raw pointer-Bashing ist im Moment scheinbar in Mode, vermutlich wegen der smart pointers von C++11 ff., die natürlich auch ihre Anwendungen haben. Deshalb braucht man aber nicht den Eindruck vermitteln, raw pointers und new seien per se überflüssig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457338</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457338</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Sat, 20 Jun 2015 21:49:00 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sat, 20 Jun 2015 22:55:00 GMT]]></title><description><![CDATA[<p>Dann nenn mal einen einzigen Fall, new zusammen mit einem rohen Zeiger zu benutzen, bei dem die Alternativen nicht in jeder Hinsicht besser sind.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457341</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457341</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sat, 20 Jun 2015 22:55:00 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 10:39:55 GMT]]></title><description><![CDATA[<p>eine DLL mit Funktionen zur E/A und Verarbeitung von asynchron eintreffenden Datenpaketen, die als Objekte verwaltet werden. Zu jedem Zeitpunkt ist null oder ein Datenpaket-Objekt ausgewählt und dazu an einen globalen Zeiger gebunden; in letzterem Fall beziehen sich die folgenden Funktionsaufrufe auf das ausgewählte Objekt. Zeitpunkt und Reihenfolge des Eintreffens der Datenpakete ist ebensowenig vorhersehbar wie die Festlegung des aktuell ausgewählten Pakets; Zeitpunkt, Art und Argumente der Funktionsaufrufe zur E/A und Verarbeitung der Datenpakete.</p>
<p>weitere Anwendungen:</p>
<p>Interfacing mit C;<br />
Objekte mit genau bekannter Lebensdauer und mehreren Benutzern;<br />
legacy code;</p>
<p>Beispiele und Übungsaufgaben aus Textbüchern lassen sich nicht immer 1:1 auf die Praxis bei gegebenen Randbedingungen in Industrie und Lehre übertragen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457355</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457355</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Sun, 21 Jun 2015 10:39:55 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 11:52:33 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>eine DLL mit Funktionen zur E/A und Verarbeitung von asynchron eintreffenden Datenpaketen, die als Objekte verwaltet werden. Zu jedem Zeitpunkt ist null oder ein Datenpaket-Objekt ausgewählt und dazu an einen globalen Zeiger gebunden; in letzterem Fall beziehen sich die folgenden Funktionsaufrufe auf das ausgewählte Objekt. Zeitpunkt und Reihenfolge des Eintreffens der Datenpakete ist ebensowenig vorhersehbar wie die Festlegung des aktuell ausgewählten Pakets; Zeitpunkt, Art und Argumente der Funktionsaufrufe zur E/A und Verarbeitung der Datenpakete.</p>
</blockquote>
<p>Ich muss zugeben, dass ich mit deinem Beispiel nichts anzufangen weiss. Wichtig ist für mich: Wem gehört das Objekt? (sprich: Wer gibt es wieder frei?). Nackte Zeiger an sich sind völlig in Ordnung, die verwende ich auch massenhaft. Allerdings ist keiner davon ein &quot;besitzender&quot; Zeiger, der irgendwann ein <code>delete</code> oder <code>free</code> oder ähnliches benötigt. D.h. es existiert irgendwo im Programm ein <code>unique_ptr</code> / <code>shared_ptr</code> oder eine Member/Stack-Variable von dem der Pointer via addressof-Operator geholt wurde, die der eigentliche Besitzer der Objektinstanz ist, und sicherstellt, dass der Pointer mindestens so lange gültig ist, wie darauf zugegriffen wird.</p>
<p>Kommt der Pointer aus der DLL, dann ist es entweder nicht meine Aufgabe, das Objekt wieder freizugeben, oder aber ich muss eine <code>destroyObject()</code> -Funktion oder ähnliches aufrufen. Im letzteren Fall packe ich den Pointer üblicherweise in einen Smart Pointer mit speziellem Deleter, der <code>destroyObject()</code> automatisch aufruft.</p>
<p>großbuchstaben schrieb:</p>
<blockquote>
<p>weitere Anwendungen:</p>
<p>Interfacing mit C;</p>
</blockquote>
<p>Lustigerweise arbeite ich gerade an einem Projekt, bei dem ich intensiv mit C-Bibliotheken zu tun habe, und ich muss sagen, dass ich dabei bisher sehr gute Erfahrungen mit <code>unique_ptr</code> / <code>shared_ptr</code> oder aber auch <code>Microsoft::WRL:ComPtr</code> (Teile des Projekts verwenden unter Windows DirectX) gemacht habe.</p>
<p>Eine der verwendeten Bibliotheken nutzt z.B. intensiv GLib/GObject, bei denen man oft Objekte in die Hand bekommt, bei denen man sich selbst darum kümmern muss, deren Referenzzähler zu dekrementieren, wenn man damit fertig ist. Ich muss sagen, dass gerade der <code>unique_ptr</code> in diesen Fällen eine ziemliche Erleichterung ist:</p>
<pre><code>struct GObjectDeleter
{
    inline void operator()(gpointer object)
    {
        assert(G_IS_OBJECT(object));
        g_object_unref(object);
    }
};

std::unique_ptr&lt;IrgendeineGObjectKlasse, GObjectDeleter&gt; object(gib_mir_objekt_mit_inkrementiertem_referenzzaehler());
</code></pre>
<p>... das erspart eine ganze Menge redundante <code>g_object_unref()</code> mit denen man sonst alle nur erdenklichen Code-Pfade zupflastern muss, wenn man nicht auf unübersichtliche <code>goto</code> -Anweisungen zurückgreifen will.</p>
<p>großbuchstaben schrieb:</p>
<blockquote>
<p>Objekte mit genau bekannter Lebensdauer und mehreren Benutzern;</p>
</blockquote>
<p>Wie eingangs erwähnt, irgendwer ist der Besitzer über den sich die &quot;bekannte Lebensdauer&quot; definiert. Ich habe z.B. auch Objkete in meinen Projekten die immer einem Elternobjekt zugeordnet sind, und höchstens so lange leben wie das Elternobjekt. In diesem Fall sehe ich ein Problem darin, wenn die Kinder einen nackten Eltern-Pointer haben - schließlich ist das kein &quot;besitzender&quot; Zeiger.</p>
<p>großbuchstaben schrieb:</p>
<blockquote>
<p>legacy code;</p>
</blockquote>
<p>Ja, da kommt man vielleicht manchmal nicht drumherum, es schadet aber nicht für neue Code-Teile trotzdem auf die Smart-Pointer zurückzugreifen und an den Schnittstellen ähnlich zu verfahren wie bei C-Bibliotheken (s.o.)</p>
<p>Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457359</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457359</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sun, 21 Jun 2015 11:52:33 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 17:22:37 GMT]]></title><description><![CDATA[<p>Finnegan schrieb:</p>
<blockquote>
<p>Wichtig ist für mich: Wem gehört das Objekt? (sprich: Wer gibt es wieder frei?).</p>
</blockquote>
<p>in der von mir beschriebenen Anwendung: dem Benutzer, der über die DLL externs die Funktionen abruft, mit denen die Daten verarbeitet werden. Da nur der Benutzer (bzw sein top-level Programm) weiß, wann er alle DLL Funktionen zur Verarbeitung aufgerufen hat, kann auch nur er bestimmen, wann das Datenpaket-Objekt gelöscht werden kann.</p>
<p>Ein smart pointer müßte zu diesem Zweck schon ziemlich smart sein, d.h. die Intention des Benutzers bzw top-level Programms erkennen, um zu wissen, wann das Datenpaket gelöscht werden kann, weil keine zukünftigen Funktionsabrufe mehr kommen, die sich auf das betreffende Objekt beziehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457384</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457384</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Sun, 21 Jun 2015 17:22:37 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 17:42:55 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>in der von mir beschriebenen Anwendung: dem Benutzer, der über die DLL externs die Funktionen abruft, mit denen die Daten verarbeitet werden. Da nur der Benutzer (bzw sein top-level Programm) weiß, wann er alle DLL Funktionen zur Verarbeitung aufgerufen hat, kann auch nur er bestimmen, wann das Datenpaket-Objekt gelöscht werden kann.</p>
</blockquote>
<p>Und warum nun new und rohe Pointer? Der Benutzer ist hier doch eindeutig der Besitzer.</p>
<blockquote>
<p>Interfacing mit C;</p>
</blockquote>
<p>Erzähl mal, wieso deine Schnittstelle sich für die Interna interessiert.</p>
<blockquote>
<p>Objekte mit genau bekannter Lebensdauer und mehreren Benutzern;</p>
</blockquote>
<p>Also ein automatisches Objekt?</p>
<blockquote>
<p>legacy code;</p>
</blockquote>
<p>Aha. Es ist also ein guter Grund, new und rohe Pointer benutzen, weil andere Leute auf der Welt es falsch gemacht haben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457389</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457389</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sun, 21 Jun 2015 17:42:55 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 18:21:53 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>in der von mir beschriebenen Anwendung: dem Benutzer, der über die DLL externs die Funktionen abruft, mit denen die Daten verarbeitet werden. Da nur der Benutzer (bzw sein top-level Programm) weiß, wann er alle DLL Funktionen zur Verarbeitung aufgerufen hat, kann auch nur er bestimmen, wann das Datenpaket-Objekt gelöscht werden kann.</p>
</blockquote>
<p>Es ist ja nicht so, dass Smartpointer die Objekte völlig willkürlich löschen. Man hat ja schon die Kontrolle darüber - man muss lediglich dafür sorgen, dass das Smartpointer-Objekt so lange existiert, wie das Datenpaket benötigt wird.</p>
<p>großbuchstaben schrieb:</p>
<blockquote>
<p>Ein smart pointer müßte zu diesem Zweck schon ziemlich smart sein, d.h. die Intention des Benutzers bzw top-level Programms erkennen, um zu wissen, wann das Datenpaket gelöscht werden kann, weil keine zukünftigen Funktionsabrufe mehr kommen, die sich auf das betreffende Objekt beziehen.</p>
</blockquote>
<p>Ich habe das mit den Datenpaketen zwar immer noch nicht so ganz verstanden, aber irgendwie riecht das ein wenig nach einem Fall für <code>std::shared_ptr</code> .<br />
Wenn man nicht weiss wann und für und wie lange etwas &quot;zukünftig&quot; gebraucht wird, bekommt halt jeder der (asynchron) etwas damit machen will einen Shared-Pointer auf das Datenpaket mit auf den Weg, und löscht diesen, wenn er damit fertig ist. Das <code>delete</code> passiert dann automatisch wenn alle mit dem Ding durch sind. Gerade in Multithreaded-Code ist <code>std::shared_ptr</code> oft ein wahrer Segen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>und nebenbei: So &quot;smart&quot; braucht so ein Shared Pointer dabei gar nicht zu sein. Wenn es im Programmcode keine Referenz mehr auf ein Objekt gibt (und man sich nicht hinterlistigerweise einen nicht-Shared-Pointer darauf herausgewieselt hat), dann <em>kann</em> niemand mehr darauf zugreifen oder einen Funktionsaufruf damit machen, weil niemand mehr weiss wo sich das Objekt im Speicher befindet - ergo kann man es auch ruhigen Gewissens löschen.</p>
<p>Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457399</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457399</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sun, 21 Jun 2015 18:21:53 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 18:24:59 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Und warum nun new und rohe Pointer? Der Benutzer ist hier doch eindeutig der Besitzer.</p>
</blockquote>
<p>der Benutzer sitzt aber nicht in der DLL, sondern ruft externs auf. Asynchron. Mannmannmannnmannmann ...</p>
<blockquote>
<blockquote>
<p>Objekte mit genau bekannter Lebensdauer und mehreren Benutzern;</p>
</blockquote>
<p>Also ein automatisches Objekt?</p>
</blockquote>
<p>kommt drauf an. Wenn die Erzeugung von Objekten asynchron von einer darüber liegenden Schicht veranlaßt wird, eher nicht.</p>
<blockquote>
<p>Aha. Es ist also ein guter Grund, new und rohe Pointer benutzen, weil andere Leute auf der Welt es falsch gemacht haben?</p>
</blockquote>
<p>hab' keine Lust, mich zu wiederholen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457401</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457401</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Sun, 21 Jun 2015 18:24:59 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 18:33:48 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>Finnegan schrieb:</p>
<blockquote>
<p>Wichtig ist für mich: Wem gehört das Objekt? (sprich: Wer gibt es wieder frei?).</p>
</blockquote>
<p>in der von mir beschriebenen Anwendung: dem Benutzer, der über die DLL externs die Funktionen abruft, mit denen die Daten verarbeitet werden. Da nur der Benutzer (bzw sein top-level Programm) weiß, wann er alle DLL Funktionen zur Verarbeitung aufgerufen hat, kann auch nur er bestimmen, wann das Datenpaket-Objekt gelöscht werden kann.</p>
<p>Ein smart pointer müßte zu diesem Zweck schon ziemlich smart sein, d.h. die Intention des Benutzers bzw top-level Programms erkennen, um zu wissen, wann das Datenpaket gelöscht werden kann, weil keine zukünftigen Funktionsabrufe mehr kommen, die sich auf das betreffende Objekt beziehen.</p>
</blockquote>
<p><div class="plugin-markdown"><input type="checkbox" id="checkbox67602" /><label for="checkbox67602">Du hast Ownership verstanden.</label></div><br />
Falls die Zerstörung des Objektes vom Client-Programm initiiert werden muss, dann ist der Client der Besitzer, und die Frage nach dem Smartpointer stellt sich auch nur für das Clientprogramm.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457404</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457404</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sun, 21 Jun 2015 18:33:48 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 18:39:11 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Und warum nun new und rohe Pointer? Der Benutzer ist hier doch eindeutig der Besitzer.</p>
</blockquote>
<p>der Benutzer sitzt aber nicht in der DLL, sondern ruft externs auf. Asynchron.</p>
</blockquote>
<p>Ja, und?</p>
<blockquote>
<p>Wenn die Erzeugung von Objekten asynchron von einer darüber liegenden Schicht veranlaßt wird, eher nicht.</p>
</blockquote>
<p>Ja, und? Ist &quot;asynchron&quot; für dich irgendwie ein Zauberwort für undefinierte Besitzverhältnisse?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457405</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457405</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Sun, 21 Jun 2015 18:39:11 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 19:30:05 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p><div class="plugin-markdown"><input type="checkbox" id="checkbox67603" /><label for="checkbox67603">Du hast Ownership verstanden.</label></div></p>
</blockquote>
<p><div class="plugin-markdown"><input type="checkbox" id="checkbox67604" checked="true" /><label for="checkbox67604">LOL</label></div></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457408</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457408</guid><dc:creator><![CDATA[gr0ßbuchstaben]]></dc:creator><pubDate>Sun, 21 Jun 2015 19:30:05 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 19:44:22 GMT]]></title><description><![CDATA[<p>Finnegan schrieb:</p>
<blockquote>
<p>Wenn man nicht weiss wann und für und wie lange etwas &quot;zukünftig&quot; gebraucht wird, bekommt halt jeder der (asynchron) etwas damit machen will einen Shared-Pointer auf das Datenpaket mit auf den Weg, und löscht diesen, wenn er damit fertig ist. Das <code>delete</code> passiert dann automatisch wenn alle mit dem Ding durch sind.</p>
</blockquote>
<p>eben nicht. Wann wer damit fertig ist, kann innerhalb der DLL nicht festgestellt werden, weil die Auswahl und Reihenfolge der Funktionen an einer höheren Schicht liegt, auf die die DLL keinen Zugriff hat.</p>
<p>Also nix mit automatisch löschen und sowas. Schön konservativ mit Zeiger und new.</p>
<p>Es bleibt bei dem, was ich in meinem ersten Post schrieb: raw pointers und new haben ihre Anwendungen, und damit ist die Diskussion für mich beendet.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457410</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457410</guid><dc:creator><![CDATA[großbuchstaben]]></dc:creator><pubDate>Sun, 21 Jun 2015 19:44:22 GMT</pubDate></item><item><title><![CDATA[Reply to Heap und Stack on Sun, 21 Jun 2015 20:18:41 GMT]]></title><description><![CDATA[<p>großbuchstaben schrieb:</p>
<blockquote>
<p>Finnegan schrieb:</p>
<blockquote>
<p>Wenn man nicht weiss wann und für und wie lange etwas &quot;zukünftig&quot; gebraucht wird, bekommt halt jeder der (asynchron) etwas damit machen will einen Shared-Pointer auf das Datenpaket mit auf den Weg, und löscht diesen, wenn er damit fertig ist. Das <code>delete</code> passiert dann automatisch wenn alle mit dem Ding durch sind.</p>
</blockquote>
<p>eben nicht. Wann wer damit fertig ist, kann innerhalb der DLL nicht festgestellt werden, weil die Auswahl und Reihenfolge der Funktionen an einer höheren Schicht liegt, auf die die DLL keinen Zugriff hat.</p>
<p>Also nix mit automatisch löschen und sowas. Schön konservativ mit Zeiger und new.</p>
<p>Es bleibt bei dem, was ich in meinem ersten Post schrieb: raw pointers und new haben ihre Anwendungen, und damit ist die Diskussion für mich beendet.</p>
</blockquote>
<p>Wenn du weißt, wann es sicher ist ein C++- <code>delete</code> zu machen, kannst du auch genau so gut sicherstellen, dass das Smart-Pointer-Objekt bis zu eben dieser Stelle existiert, bzw. dort stattdessen ein <code>ptr.reset()</code> machen. Es ist ja nicht so, dass der Code mit Smart Pointern dann unbedingt &quot;korrekter&quot; oder &quot;sicherer&quot; wäre (mal abgesehen davon, dass man dann das <code>delete</code> auf jeden Fall nicht &quot;vergisst&quot; und auch die Gefahr eines use-after-free minimiert).<br />
Soweit ich mich erinnere, ging es doch eigentlich darum, dass man an dieser Stelle <code>new</code> / <code>delete</code> unbedingt braucht (&quot;Anwendungen&quot; von <code>new</code> und besitzenden Raw Pointern), und so wie ich das sehe ist das hier nicht der Fall - zumindest habe ich noch kein Argument gelesen, weshalb man das Problem nicht mit einem Smart Pointer lösen könnte.</p>
<p>Mir persönlich sind ehrlich gesagt Pointer lieber, die versehentlich (automatsich) freigegeben werden und danach genullt sind (da weiss man wo der Feind steht :D), als solche bei denen ich eventuell das <code>delete</code> vergessen habe, oder schlimmer als solche die zwar gelöscht wurden, danach aber nicht genullt wurden <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Und ja, ich habe auch fertig :p</p>
<p>Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2457413</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2457413</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sun, 21 Jun 2015 20:18:41 GMT</pubDate></item></channel></rss>