<?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[Zeiger doppelt gelöscht]]></title><description><![CDATA[<p>Hallo Zusammen,</p>
<p>Ich befasse mich noch nicht lange mit C++ und habe ein Grundlegendes Zeiger Problem.</p>
<p>Es besteht folgende Situation.<br />
Ich habe 2 Klassen. In Klasse 1 Initialisiere ich einen buffer, danach wird ein IP Paket in diesen buffer geschrieben. Danach rufe ich auf der zweiten Klasse die Funktion decode auf und übergebe diesen buffer der Funktion. Diese Funktion casted diesen buffer auf zwei member pointers die die struktur abbilden des Pakets. Wird die While-Schleifen Bedingung in Klasse 1 auf False gesetzt lösche ich den buffer. Danach wird der Destruktor der Klasse 2 aufgerufen. Logischer weise muss ich hier meine allokierten speicher wieder freigeben. Das Problem ist nun das ja sowohl der buffer wie auch meine beiden member zeiger auf den selber speicher bereich zeigen. Lösche ich nun also den buffer dann ist der speicher von den member zeiger bereits freigegeben jedoch zeigen diese immer noch auf diesen speicher bereich. Nochmaliges löschen ergibt im Debug modus eine Assertmeldung.</p>
<p>Wie löst man dieses Problem? Ich habe mich ein bisschen mit Smart Pointer befasst wie auch Referenzzählung. Ist dies die einzige Methode?</p>
<p>Klasse 1:</p>
<pre><code>char* buffer = new char[ BUFFSIZE ];

	while( bedingung )
	{
		// Hier empfägt das Programm etwas und schreibt es in den buffer
		klasse2-&gt;decode( buffer );
	}

	delete [] buffer;
	buffer = 0;
</code></pre>
<p>Klasse 2:</p>
<pre><code>// Members
	IPV4* 	IpHdr;
	UDP*	UdpHdr;

	// Konstruktor
	Klasse2( void )
	: 	IpHdr( 0 ),
		UdpHdr( 0 )
	{
		// Leer
	}

	// Destruktor
	~Klasse2()
	{
		if( IpHdr )
		{
			delete IpHdr;
			IpHdr = 0;
		}

		if( UdpHdr )
		{
			delete UdpHdr;
			UdpHdr = 0;
		}
	}

	decode( char* p_buffer )
	{
		IpHdr = reinterpret_cast&lt; IPV4 * &gt;( p_buffer );

		p_buffer = p_buffer + IpHdrLength;
		UdpHdr = reinterpret_cast&lt; UDP * &gt;( p_buffer);
	}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/320558/zeiger-doppelt-gelöscht</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Jul 2026 02:40:36 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/320558.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 03 Oct 2013 07:55:24 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zeiger doppelt gelöscht on Thu, 03 Oct 2013 07:55:24 GMT]]></title><description><![CDATA[<p>Hallo Zusammen,</p>
<p>Ich befasse mich noch nicht lange mit C++ und habe ein Grundlegendes Zeiger Problem.</p>
<p>Es besteht folgende Situation.<br />
Ich habe 2 Klassen. In Klasse 1 Initialisiere ich einen buffer, danach wird ein IP Paket in diesen buffer geschrieben. Danach rufe ich auf der zweiten Klasse die Funktion decode auf und übergebe diesen buffer der Funktion. Diese Funktion casted diesen buffer auf zwei member pointers die die struktur abbilden des Pakets. Wird die While-Schleifen Bedingung in Klasse 1 auf False gesetzt lösche ich den buffer. Danach wird der Destruktor der Klasse 2 aufgerufen. Logischer weise muss ich hier meine allokierten speicher wieder freigeben. Das Problem ist nun das ja sowohl der buffer wie auch meine beiden member zeiger auf den selber speicher bereich zeigen. Lösche ich nun also den buffer dann ist der speicher von den member zeiger bereits freigegeben jedoch zeigen diese immer noch auf diesen speicher bereich. Nochmaliges löschen ergibt im Debug modus eine Assertmeldung.</p>
<p>Wie löst man dieses Problem? Ich habe mich ein bisschen mit Smart Pointer befasst wie auch Referenzzählung. Ist dies die einzige Methode?</p>
<p>Klasse 1:</p>
<pre><code>char* buffer = new char[ BUFFSIZE ];

	while( bedingung )
	{
		// Hier empfägt das Programm etwas und schreibt es in den buffer
		klasse2-&gt;decode( buffer );
	}

	delete [] buffer;
	buffer = 0;
</code></pre>
<p>Klasse 2:</p>
<pre><code>// Members
	IPV4* 	IpHdr;
	UDP*	UdpHdr;

	// Konstruktor
	Klasse2( void )
	: 	IpHdr( 0 ),
		UdpHdr( 0 )
	{
		// Leer
	}

	// Destruktor
	~Klasse2()
	{
		if( IpHdr )
		{
			delete IpHdr;
			IpHdr = 0;
		}

		if( UdpHdr )
		{
			delete UdpHdr;
			UdpHdr = 0;
		}
	}

	decode( char* p_buffer )
	{
		IpHdr = reinterpret_cast&lt; IPV4 * &gt;( p_buffer );

		p_buffer = p_buffer + IpHdrLength;
		UdpHdr = reinterpret_cast&lt; UDP * &gt;( p_buffer);
	}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2357523</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2357523</guid><dc:creator><![CDATA[Franklin31289]]></dc:creator><pubDate>Thu, 03 Oct 2013 07:55:24 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger doppelt gelöscht on Thu, 03 Oct 2013 08:15:35 GMT]]></title><description><![CDATA[<p>zunächst mal passt delete nicht zu new[].</p>
<p>mögliche lösungen für die fragestellung:<br />
1. Klasse2::decode macht eine deep copy und verwaltet es dann selbst<br />
2. du löschst den buffer ganz einfach nicht selbst sondern überlässt es dem destruktor<br />
3. du löschst den buffer im destruktor nicht, ist ja nicht die aufgabe von Klasse2</p>
<p>aber allgemein sind wir hier eigentlich in c++, arbeite also lieber mit containern und iteratoren</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2357526</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2357526</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 03 Oct 2013 08:15:35 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger doppelt gelöscht on Thu, 03 Oct 2013 08:24:55 GMT]]></title><description><![CDATA[<p>Welche der beiden Klassen <em>besitzt</em> nun diesen Buffer? Diese solle übrigens nicht mit rohem <code>new</code> / <code>delete</code> (letzteres schon gar nicht) arbeiten, sondern mit <code>std::string</code> , welches du sicherlich schon kennst. Von diesem kannst du einfach die Adresse des ersten Zeichens nehmen, dann hast du schon einen nullterminierten, beschreibbaren String.</p>
<p>Natürlich kannst du den String aber auch einfach kopieren, das ist eine der Vorteile beim <code>std::string</code> - und lohnt sich hier, da es nicht weiter darauf ankommt, dass beide Klasse denselben String bearbeiten. Natürlich nur wenn der String nicht sehr groß ist, und eine solche Kopie performancetechnisch verkraftbar.</p>
<p>Ich wundere mich allerdings, wieso du in jedem Schleifendurchlauf durch <code>decode</code> die in Klasse 2 befindlichen Zeiger setzen lässt.</p>
<pre><code>if( IpHdr )
        {
            delete IpHdr;
</code></pre>
<p>Die Abfrage ist völlig überflüssig: <code>delete</code> nimmt auch Nullzeiger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2357527</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2357527</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Thu, 03 Oct 2013 08:24:55 GMT</pubDate></item></channel></rss>