<?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[Delete eines dynamischen 2D Arrays verusacht Absturz]]></title><description><![CDATA[<p>Wie schon der Titel verrät geht es um das Löschen eines dynamischen Arrays.<br />
Der genannte Fehler ist aber ewtas merkwürdig, denn er passiert nur beim 3 oder 4 Aufruf mit dem delete Befehl.</p>
<p>Hier die Vorgehensweise wie der Speicher allokiert und gelöscht wird :<br />
Beide Funktionen stammen von <a href="http://www.codeguru.com/forum/showthread.php?s=&amp;threadid=297838" rel="nofollow">http://www.codeguru.com/forum/showthread.php?s=&amp;threadid=297838</a>, obwohl die Vorgehensweise dort jetzt geändert wurden ist.</p>
<pre><code class="language-cpp">template &lt; typename T &gt;
T **Allocate2DArray( int nRows, int nCols)
{
    //(step 1) allocate memory for array of elements of column
    T **ppi = new T*[nRows];

    //(step 2) allocate memory for array of elements of each row
    T *curPtr = new T [nRows * nCols];

    // Now point the pointers in the right place
    for( int i = 0; i &lt; nRows; ++i)
    {
        *(ppi + i) = curPtr;
         curPtr += nCols;
    }
    return ppi;
}

template &lt; typename T &gt;
void Free2DArray(T** Array)
{
    delete [] *Array;
    delete [] Array;
}
</code></pre>
<p>Codefragment aus meinem Programm</p>
<pre><code class="language-cpp">class Map
{
    // [...]
    public :
        Map();
        ~Map();
    // [...]

    protected :

    // [...]

    private :

        //!2d array
        Tile** map_Data;
        //!1d Array für Objekte
        Object* obj_Data;
        //! Map merkmale :
        int   Map_x,
              Map_y;

};

// Der Einsatz :
Map::Map()
{
    // Set Default settings :
    Map_x = 1;
    Map_y = 1;

    // &quot;Save&quot; pointers
    map_Data = Allocate2DArray &lt; Tile &gt; (Map_x,Map_y);
    obj_Data = NULL;
}

Map::~Map()
{

    Free2DArray &lt; Tile &gt; ( map_Data );   /// Hier liegt der Fehler
    map_Data = NULL;

    delete [] obj_Data;
    obj_Data = NULL;

}
</code></pre>
<p>Wobei für Tile gilt :</p>
<pre><code class="language-cpp">struct Tile
{
    short gfxID;
    short Frame;
    short Framewait;

};
</code></pre>
<p>Ist die Löschfunktion nun ganz falsch ?<br />
Ich habe viele Varianten genutzt, wie z.b. mit einer For-Schleife die Pointer im Array zu löschen, doch alles führt zum gleichen Ergebnis.</p>
<p>Wie löscht man den Speicher richtig ?<br />
Oder liegt es letztenddlich wohlmöglich an meinem Code ?</p>
<p>Ich danke im Voraus : D</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/279789/delete-eines-dynamischen-2d-arrays-verusacht-absturz</link><generator>RSS for Node</generator><lastBuildDate>Mon, 24 Aug 2026 07:15:43 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/279789.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 03 Jan 2011 18:01:44 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Mon, 03 Jan 2011 18:01:44 GMT]]></title><description><![CDATA[<p>Wie schon der Titel verrät geht es um das Löschen eines dynamischen Arrays.<br />
Der genannte Fehler ist aber ewtas merkwürdig, denn er passiert nur beim 3 oder 4 Aufruf mit dem delete Befehl.</p>
<p>Hier die Vorgehensweise wie der Speicher allokiert und gelöscht wird :<br />
Beide Funktionen stammen von <a href="http://www.codeguru.com/forum/showthread.php?s=&amp;threadid=297838" rel="nofollow">http://www.codeguru.com/forum/showthread.php?s=&amp;threadid=297838</a>, obwohl die Vorgehensweise dort jetzt geändert wurden ist.</p>
<pre><code class="language-cpp">template &lt; typename T &gt;
T **Allocate2DArray( int nRows, int nCols)
{
    //(step 1) allocate memory for array of elements of column
    T **ppi = new T*[nRows];

    //(step 2) allocate memory for array of elements of each row
    T *curPtr = new T [nRows * nCols];

    // Now point the pointers in the right place
    for( int i = 0; i &lt; nRows; ++i)
    {
        *(ppi + i) = curPtr;
         curPtr += nCols;
    }
    return ppi;
}

template &lt; typename T &gt;
void Free2DArray(T** Array)
{
    delete [] *Array;
    delete [] Array;
}
</code></pre>
<p>Codefragment aus meinem Programm</p>
<pre><code class="language-cpp">class Map
{
    // [...]
    public :
        Map();
        ~Map();
    // [...]

    protected :

    // [...]

    private :

        //!2d array
        Tile** map_Data;
        //!1d Array für Objekte
        Object* obj_Data;
        //! Map merkmale :
        int   Map_x,
              Map_y;

};

// Der Einsatz :
Map::Map()
{
    // Set Default settings :
    Map_x = 1;
    Map_y = 1;

    // &quot;Save&quot; pointers
    map_Data = Allocate2DArray &lt; Tile &gt; (Map_x,Map_y);
    obj_Data = NULL;
}

Map::~Map()
{

    Free2DArray &lt; Tile &gt; ( map_Data );   /// Hier liegt der Fehler
    map_Data = NULL;

    delete [] obj_Data;
    obj_Data = NULL;

}
</code></pre>
<p>Wobei für Tile gilt :</p>
<pre><code class="language-cpp">struct Tile
{
    short gfxID;
    short Frame;
    short Framewait;

};
</code></pre>
<p>Ist die Löschfunktion nun ganz falsch ?<br />
Ich habe viele Varianten genutzt, wie z.b. mit einer For-Schleife die Pointer im Array zu löschen, doch alles führt zum gleichen Ergebnis.</p>
<p>Wie löscht man den Speicher richtig ?<br />
Oder liegt es letztenddlich wohlmöglich an meinem Code ?</p>
<p>Ich danke im Voraus : D</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2001914</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2001914</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Mon, 03 Jan 2011 18:01:44 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Mon, 03 Jan 2011 18:19:59 GMT]]></title><description><![CDATA[<p>Könnte das ein <a href="http://de.wikipedia.org/wiki/Dreierregel_%28C%2B%2B%29" rel="nofollow">Dreierregel</a>-verletzender Bug sein? Das könnte ich mir zumindest vorstellen. Anhand des Programmtexts, den Du zeigst, geht das leider nicht hervor. Dafür fehlt da einiges. Verstecken sich hinter den &quot;[...]&quot; noch ein benutzerdefinierter Kopierkonstruktor und Zuweisungsoperator?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2001930</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2001930</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Mon, 03 Jan 2011 18:19:59 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Mon, 03 Jan 2011 18:26:04 GMT]]></title><description><![CDATA[<p>Bisher habe ich noch keine Operator-Funktionen miteingebaut, da ich bisher den Pointer einfach auf public gestellt habe.</p>
<p>Nun was also nur passiert ist,dass der Konstruktor dem Pointer Speicher für ein<br />
1x1 Array belegt.<br />
Der Desonstruktor wiederum soll diesen Speicher wieder freigeben.</p>
<p>Die Funktionen, die ich weggelassen habe, sind nur weitere Funktionen, die anhand einer angegebenen Datei den Pointer füllen sollen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2001933</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2001933</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Mon, 03 Jan 2011 18:26:04 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Mon, 03 Jan 2011 19:27:06 GMT]]></title><description><![CDATA[<p>Du solltest unbedingt den Hinweis zur Dreierregel beachten. Weiter ist es möglich, dass der Fehler nicht dort steckt, wo Du ihn suchst. Zumindest sehe ich keinen. Ich kann nur raten, was Dein restliches Programm angeht. Und ich rate: Dreierregel-Verletzung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2001954</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2001954</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Mon, 03 Jan 2011 19:27:06 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Wed, 05 Jan 2011 20:11:17 GMT]]></title><description><![CDATA[<p>Ok, ich habe den Fehler nun gefunden.<br />
Dein Hinweis stimmt doch.<br />
Bevor die Klasse wegen dem Gültigkeitsbereich gelöscht wird, habe ich eine Funktion dazu genutzt den (map_Data) pointer vor dem Destruktor zu löschen.<br />
Jetzt überlasse ich das Löschen dem dtor und es geht einwandfrei.</p>
<p>Es stellen sich mir aber einige fragen.<br />
Im Ctor kann ich den (obj_data)pointer auf NULL stellen, warum geht dies nicht mit den (map_data) pointer?<br />
Liegt es daran, dass (map_data) ein Pointer auf Pointer ist?<br />
Wenn ich dem pointer stattdessen mit :</p>
<pre><code class="language-cpp">Map::Map()
{
    // Set Default settings :
    Map_x = 1;
    Map_y = 1;

    // &quot;Save&quot; pointers
    map_Data = Allocate2DArray &lt; Tile &gt; (Map_x,Map_y);
    obj_Data = NULL;
}
</code></pre>
<p>Speicher allokiere, stürzt das Programm nicht ab.<br />
Wie kann ich ein solchen Pointer sicher auf NULL zuweissen?</p>
<p>Hinderlich ist es auch, dass ich keinen Speicher neubelegen kann, da ich ja immer in der Lage sein muss, eine neue Datei laden zu können, also (map_Data) mit neuen Daten wieder besetzen.<br />
Nun frage ich mich, ob delete wirklich sicher auf NULL- Pointer reagiert.</p>
<pre><code class="language-cpp">// Auszug aus einer Klasse die eine Instanz der Klasse Map (Level) enthält.

Editor::~Editor()
{
    // delete the currently loaded map data
    Level.DeleteMap();

}

// Auszug aus der Map Klase mit der gewünschten Funktion 
void Map::DeleteMap()
{
    Free2DArray &lt; Tile &gt; ( map_Data ); // Fehler
    map_Data = NULL;
}
</code></pre>
<p>Mit dem löschen vom &quot;Editor&quot; verlange ich das Löschen des (map_Data) Pointers an, was aber hier wieder an der gleichen Stelle scheitert wie vorhin.<br />
Ist so ein Eingriff generell schlecht und sollte ich den Dtor das Reinigen überlassen ?<br />
Aber wie komme ich so aufs Löschen des (map_Data) Pointers, wenn ich eine neue Datei laden möchte ?</p>
<p>Ich hoffe das Problem ist verständlich genug</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002903</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002903</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Wed, 05 Jan 2011 20:11:17 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Wed, 05 Jan 2011 20:15:53 GMT]]></title><description><![CDATA[<p>Achja und eine Zuweisungsfunktion wurde in den privaten Bereich von Map deklariert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002905</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002905</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Wed, 05 Jan 2011 20:15:53 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Wed, 05 Jan 2011 20:48:56 GMT]]></title><description><![CDATA[<p>Du machst es einem nicht leicht Dir zu helfen. Diese kurzen Code-Fragmente sind nicht besonders aufschlussreich. Schau nochmal in der FAQ nach Tipps bzgl Stellen von Fragen. Alternativ kannst Du Dir auch ein schlaues C++ Buch besorgen. Ich habe ein bisschen den Eindruck, dass Du das eine oder andere wichtige an C++ nicht verstanden hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002920</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002920</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Wed, 05 Jan 2011 20:48:56 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Wed, 05 Jan 2011 20:52:11 GMT]]></title><description><![CDATA[<p>Schonmal daran gedacht die STL zu verwenden?</p>
<pre><code class="language-cpp">std::vector&lt;std::pair&lt;int, int&gt; &gt;
</code></pre>
<p>Schon hat man eine einfachen leicht zu verwendende 2D-Vector.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002921</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002921</guid><dc:creator><![CDATA[STL]]></dc:creator><pubDate>Wed, 05 Jan 2011 20:52:11 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Wed, 05 Jan 2011 20:56:09 GMT]]></title><description><![CDATA[<p>Falsch! Einen 2-D Vector hast du nur mit std::vector&lt; std::vector &lt; Tile &gt; &gt;</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2002924</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2002924</guid><dc:creator><![CDATA[HighLigerBiMBam]]></dc:creator><pubDate>Wed, 05 Jan 2011 20:56:09 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Thu, 06 Jan 2011 08:02:15 GMT]]></title><description><![CDATA[<p>Ich bedanke mich für die Tips, aber ich möchte zuerst wissen, warum ein 2D Pointer nicht auf NULL zeigen kann, bevor ich was anderes probieren will.</p>
<p>Hier ein Beispiel, was das Problem betrifft.</p>
<pre><code class="language-cpp">class Map
{
    public :
        Map(){

            Mapx = 1;
            Mapy = 1;

            map_Data = Allocate2DArray &lt; int &gt; (Mapx, Mapy);

        }
        ~Map(){

            Free2DArray &lt; int &gt; (map_Data);

        }
        void MakeMap(unsigned int x, unsigned int y){

            FreeMap();

            Mapx = x;
            Mapy = y;

            Free2DArray &lt; int &gt; ( map_Data );
            map_Data = Allocate2DArray &lt; int &gt; (Mapx, Mapy);

        }
    private :
        void FreeMap(){

            Free2DArray &lt; int &gt; (map_Data);

            map_Data = NULL; // Fehler

            Mapx = 0;
            Mapy = 0;

        }
        int Mapx, Mapy;
        int** map_Data;
};

int main ()
{

    Map level;
    level.MakeMap(2,3);
    return 0;

}
</code></pre>
<p>Besitze ich ein falsches Verständniss für Pointer ?<br />
Bitte klärt mich auf, was das Problem angeht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003008</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003008</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Thu, 06 Jan 2011 08:02:15 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Thu, 06 Jan 2011 09:10:15 GMT]]></title><description><![CDATA[<p>1.: Warum löschst du dein 2D Array 2mal (einmal in Freemap und einmal nachdem du Mapx und Mapy x und y zugewiesen hast)?</p>
<p>Und ansonsten probier doch mal</p>
<pre><code class="language-cpp">*map_data=NULL;
</code></pre>
<p>Dann tust du ja nur einen normalen Zeiger auf NULL setzen und man könnte über diesen auch nicht irgendwodrauf zugreifen, da es ja indirekt ein NULL-Zeiger ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003035</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003035</guid><dc:creator><![CDATA[Calk]]></dc:creator><pubDate>Thu, 06 Jan 2011 09:10:15 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Thu, 06 Jan 2011 09:13:42 GMT]]></title><description><![CDATA[<p>Dman schrieb:</p>
<blockquote>
<p>Ich bedanke mich für die Tips, aber ich möchte zuerst wissen, warum ein 2D Pointer nicht auf NULL zeigen kann, bevor ich was anderes probieren will.</p>
</blockquote>
<p>Ich gehe davon aus, dass Du mit &quot;2D Zeiger&quot; einen Zeiger auf einen Zeiger meinst. Ein Zeiger kann nicht auf &quot;Null zeigen&quot;. Aber ein Zeiger kann &quot;Null sein&quot;. Das gilt natürlich auch für Zeiger auf Zeiger.</p>
<p>Dman schrieb:</p>
<blockquote>
<p>Hier ein Beispiel, was das Problem betrifft.</p>
<pre><code class="language-cpp">class Map
{
    public :
        Map(){
            Mapx = 1;
            Mapy = 1;
            map_Data = Allocate2DArray &lt; int &gt; (Mapx, Mapy);
        }
        ~Map(){
            Free2DArray &lt; int &gt; (map_Data);
        }
        void MakeMap(unsigned int x, unsigned int y){
            FreeMap();
            Mapx = x;
            Mapy = y;
            Free2DArray &lt; int &gt; ( map_Data );
            map_Data = Allocate2DArray &lt; int &gt; (Mapx, Mapy);
        }
    private :
        void FreeMap(){
            Free2DArray &lt; int &gt; (map_Data);
            map_Data = NULL; // Fehler
            Mapx = 0;
            Mapy = 0;

        }
        int Mapx, Mapy;
        int** map_Data;
};
</code></pre>
</blockquote>
<p>Du hast anscheinend die Dreierregel, obwohl ich 2mal darauf hingewiesen habe, nicht verstanden bzw nicht nachrecherchiert. Außerdem: Was für ein Fehler soll &quot;Fehler&quot; sein? Kannst Du Dir nicht denken, dass man als Helfer auch gern die Fehlermeldung lesen würde? So kann ich wieder nur RATEN. Und ich rate, dass Du keinen entsprechenden Header inkludiert hast, der das Makro NULL definiert. NULL ist nämlich kein Schlüsselwort. Verwende stattdessen einfach die Ganzzahlkonstante 0.</p>
<p>Als kleine Fingerübung ist dieser Ansatz schon OK, da Du dadurch Resourcenverwaltung und Co lernst. Aber Du kannst es auch VIEL einfacher haben, indem Du einfach einen std::vector als Datenelement verwendest.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003039</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003039</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Thu, 06 Jan 2011 09:13:42 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Thu, 06 Jan 2011 09:34:32 GMT]]></title><description><![CDATA[<p>Bezugnehmend auf deinen letzten geposteten code:</p>
<p>In MakeMap rufst du FreeMap auf. FreeMap ruft Free2DArray auf und setzt map_Data auf NULL. Soweit alles ok.</p>
<p>Rücksprung in Makemap. Du rufst Free2DArray wieder auf mit map_Data (jetzt NULL-Pointer). In Free2DArray dereferenziert du map_Data ---&gt; schlechte Idee und dein Problem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003048</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003048</guid><dc:creator><![CDATA[inter2k3]]></dc:creator><pubDate>Thu, 06 Jan 2011 09:34:32 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Fri, 07 Jan 2011 06:19:05 GMT]]></title><description><![CDATA[<p>Nun gut, ich kann jetzt endlich einen Zeiger auf Zeiger auf NULL setzen.</p>
<p>Dass ich die Dreierregel so nicht nachrecherchiert stimmt nicht.<br />
Soweit ich lesen konnte besagt diese, dass wenn ein Kontruktur, Destruktur oder eine Zuweisungsoperatorfunktion vom Programmierer angegeben ist man auch die anderen zwei deklarieren sollte.<br />
Ich habe lediglich vergessen das im Beispiel anzugeben.</p>
<p>So jetzt werde ich mich darum bemühen, den Vector du benutzen.</p>
<p>Ich danke für eure Hilfe !</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003417</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003417</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Fri, 07 Jan 2011 06:19:05 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Fri, 07 Jan 2011 08:26:28 GMT]]></title><description><![CDATA[<p>Die besagten drei sind:</p>
<ul>
<li>copy constructor</li>
<li>assignment operator</li>
<li>destructor</li>
</ul>
<p>Stell dir folgendes Szenario vor:<br />
Du erstellst ein Objekt des Typs Map, welches als data-member Zeiger besitzt. Diese zeigen in deinem Fall auf im Konstruktor dynamisch allozierten Speicher.</p>
<p>Nun übergibst du das Map-Objekt per value an eine Funktion. Dabei wird es kopiert (copy constructor). Da du keinen angegeben hast, wird einer vom compiler erstellt, der allerdings nur eine flatcopy / shallow copy durchführt.<br />
Will heissen, dass zwar der Pointer kopiert wird, aber die Kopie auf die gleiche Speicheradresse zeigt wie das Orginal.</p>
<p>Beim Verlassen der Funktion verliert das kopierte Objekt seine Gültigkeit und wird daher zerstört. Im von dir angegebenen Destructor gibst du den Speicher auf den der Pointer zeigt wieder frei.</p>
<p>Allerdings zeigt der Pointer des ursprünglichen Map-Objekts (von dem die Kopie angelegt wurde) weiterhin auf die Adresse --&gt; ein dangling pointer.<br />
Es wäre jetzt fatal die dort gespeicherten Daten zu benutzen, zu manipulieren oder zu versuchen, den Speicher freizugeben.</p>
<p>Die Lösung wäre also die Angabe eines copy constructors, der neuen Speicher alloziert, die Daten des Speicherbereis kopiert und den Pointer der Kopie entsprechend auf den neu allozierten Speicher setzt. Das nennt man deep-copy.</p>
<p>Ich hoffe es ist klar, dass in einem solchen Fall wohl auch unbedingt die Angabe eines assignment-operators nötig ist (tust du es nicht, werden memory leaks die Folge sein)<br />
(dabei darauf achten, dass du auf self-assignment testest).</p>
<p>Einige Beispiele für den Fall, dass dir nicht bewusst ist, wann z.B. Kopien erstellt werden:</p>
<ul>
<li>Initialisieren mit Objekt des gl. Typs</li>
<li>call-by-value bei Funktionsaufrufen</li>
<li>return-value</li>
<li>Verwendung der STL-Container oder der meisten STL-Algorithmen<br />
etc.</li>
</ul>
]]></description><link>https://www.c-plusplus.net/forum/post/2003436</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003436</guid><dc:creator><![CDATA[inter2k3]]></dc:creator><pubDate>Fri, 07 Jan 2011 08:26:28 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Fri, 07 Jan 2011 13:53:23 GMT]]></title><description><![CDATA[<p>ok, ich hoffe ich habe die Dreierregel jetzt verstanden.<br />
Eine copy, bzw assigment Funktion für die Klasse Map wäre folglich :</p>
<pre><code class="language-cpp">Map::Map&amp; operator=(const Map cpy)
{
   Mapx = cpy.Mapx;
   Mapy = cpy.Mapy;

   FreeMap();
   map_Data = Allocate2DArray &lt; int &gt; (Mapx, Mapy);

   // &quot;Depp-copy&quot;
   for (int i = 0;i &lt; Mapy ; i++)
   {
      for (int j = 0;j &lt; Mapx ; j++)
      map_Data[i][j] = cpy.map_Data[i][j];
   }

   return *this;
}
</code></pre>
<p>Wenn ich nun aber in jeder Session meines Programmes jeweils nur eine Instanz der Klasse Map enstehen lasse bin ich doch dazu befugt die Dreierregel zu brechen oder sehe ich das falsch.<br />
Es gäbe ja keinen Grund sich vor falschen Pointern zu schützen , wenn man letztlich keine Kopie einer Map Isntanz vor hat/programmiert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003650</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003650</guid><dc:creator><![CDATA[Dman]]></dc:creator><pubDate>Fri, 07 Jan 2011 13:53:23 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Fri, 07 Jan 2011 14:50:14 GMT]]></title><description><![CDATA[<p>Dman schrieb:</p>
<blockquote>
<p>Wenn ich nun aber in jeder Session meines Programmes jeweils nur eine Instanz der Klasse Map enstehen lasse bin ich doch dazu befugt die Dreierregel zu brechen oder sehe ich das falsch.</p>
</blockquote>
<p>Selbst dann solltest du sicher stellen, das keine unabsichtlichen Kopien/Zuweisungen im Code vorkommen (Deklariere sowohl den Kopierkonstruktor als auch Zuweisungsoperator privat, und implementiere sie nicht).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003686</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003686</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Fri, 07 Jan 2011 14:50:14 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Fri, 07 Jan 2011 14:52:16 GMT]]></title><description><![CDATA[<p>Ergänzend zu asc kannst du auch eine Klasse uncopyable erstellen und davon erben. Oder du nimmt boost noncopyable.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003691</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003691</guid><dc:creator><![CDATA[HighLigerBiMBam]]></dc:creator><pubDate>Fri, 07 Jan 2011 14:52:16 GMT</pubDate></item><item><title><![CDATA[Reply to Delete eines dynamischen 2D Arrays verusacht Absturz on Fri, 07 Jan 2011 15:43:20 GMT]]></title><description><![CDATA[<p>Dman schrieb:</p>
<blockquote>
<p>ok, ich hoffe ich habe die Dreierregel jetzt verstanden.<br />
Eine copy, bzw assigment Funktion für die Klasse Map wäre folglich :</p>
<pre><code class="language-cpp">Map::Map&amp; operator=(const Map cpy)
{
   Mapx = cpy.Mapx;
   Mapy = cpy.Mapy;

   FreeMap();
   map_Data = Allocate2DArray &lt; int &gt; (Mapx, Mapy);
   
   // &quot;Depp-copy&quot;
   for (int i = 0;i &lt; Mapy ; i++)
   {
      for (int j = 0;j &lt; Mapx ; j++)
      map_Data[i][j] = cpy.map_Data[i][j];
   }

   return *this;
}
</code></pre>
</blockquote>
<p>Wenn Du sagst &quot;copy, bzw assigment Funktion&quot; und dann nur den Zuweisungsoperator zeigst, hast Du dann den Kopierkonstruktor vergessen oder willst Du ihn einfach nicht zeigen? Falls ersteres: Da gehört noch ein Kopierkonstruktor dazu!</p>
<p>Ich hoffe, Du weißt, dass Kopierkonstruktor und Zuweisungsoperator ggf vom Compiler selbst -- eventuell falsch -- implementiert werden. Daher gibt's ja auch die Dreierregel.</p>
<p>So schreibt man auch keinen Zuweisungsoperator. Ich sehe zwar keinen Fehler, aber das sollte recht unperformant sein; denn wenn Du so etwas schreibst wie</p>
<pre><code>a = b;
</code></pre>
<p>werden zwei Kopien erzeugt. Zunächst wird von b eine Kopie erzeugt (-&gt; cpy) und dann kopierst Du den Inhalt von cpy noch nach a.</p>
<p>Ich verweise hier mal auf den Copy &amp; Swap Trick.</p>
<p>Deine Klasse sollte (mit Copy-&amp;-Swap) in etwa so aussehen:</p>
<pre><code class="language-cpp">class Map
{
public:
  Map();                    // Default-Konstruktor
  Map(int xdim, int ysim);
  Map(Map const&amp;);          // Kopier-konstruktor
  ~Map();                   // Destruktor
  void swap(Map &amp; that);    // Vertauscht den Inhalt zweier Objekte
  Map&amp; operator=(Map temp) { swap(temp); return *this; }

  //... noch ein paar Operationen

private:
  int xdim_;
  int ydim_;
  ElemType** elems_;
};

inline void swap(Map &amp; a, Map &amp; b) {a.swap(b);}
</code></pre>
<p>wobei man bei swap natürlich nur die zwei ints und den Zeiger austauschen muss.</p>
<p>Wenn du es ohne Copy-&amp;-Swap Trick machen willst, sollte es so aussehen:</p>
<pre><code class="language-cpp">class Map
{
public:
  Map();                    // Default-Konstruktor
  Map(int xdim, int ysim);
  Map(Map const&amp;);          // Kopier-konstruktor
  ~Map();                   // Destruktor
  Map&amp; operator=(Map const&amp; temp);

  //... noch ein paar Operationen

private:
  int xdim_;
  int ydim_;
  ElemType** elems_;
};

...

Map&amp; Map::operator=(Map const&amp; temp)
{
  if (this==&amp;temp) return *this; // Selbstzuweisung abfangen
  ...
  return *this;
}
</code></pre>
<p>Und wenn Du das fehlerfrei geschafft hast, dann kannst Du das Ding mit 'nem STL-Container komplett neu machen:</p>
<pre><code class="language-cpp">class Map
{
public:
  Map();
  Map(int xdim, int ysim);

private:
  int xdim_;
  int ydim_;
  std::vector&lt;ElemType&gt; elems_;
};
</code></pre>
<p>Beachte: Man muss hier gar keinen Kopierkonstruktor, Destruktor und Zuweisungsoperator selbst deklarieren, da die vom Compiler-generierten Versionen genau das richtige tun. Du solltest also beim Klassen-Design darauf Wert legen, dass benutzerdefinierter Destruktor und Kopier-Operationen erst gar nicht nötig sind, falls möglich.</p>
<p>Dman schrieb:</p>
<blockquote>
<p>Wenn ich nun aber in jeder Session meines Programmes jeweils nur eine Instanz der Klasse Map enstehen lasse bin ich doch dazu befugt die Dreierregel zu brechen oder sehe ich das falsch.</p>
</blockquote>
<p>Wenn so ein Objekt nicht kopieren brauchst, dann solltest Du es auch wenigstens verbieten, so dass ein Kopierversuch zu einem Kompilierfehler führt. Das kann man erreichen indem Kopierkonstruktor und Zuweisungsoperator privat deklariert werden und undefiniert bleiben -- oder alternativ die Klasse von so etwas wie boost::noncopyable erben lässt.</p>
<p>Mit welchem Buch lernst Du C++? Steht da so'was nicht drin? Hast Du Scott Meyers' &quot;Effective C++&quot; gelesen? Falls nicht, unbedingt kaufen!</p>
<p>kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2003724</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2003724</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 07 Jan 2011 15:43:20 GMT</pubDate></item></channel></rss>