<?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[std::map im Copy-Constructor überschreibt Daten]]></title><description><![CDATA[<p>Ich bin gestern auf ein mir unerklärliches Problem gestoßen. Ich habe ein Design der folgenden Art:</p>
<pre><code class="language-cpp">class A {
private:
    B b;
public:
    B getB() { return b; }
};

class B {
private:
    std::map&lt;int, float*&gt; map;
public:
    B(B &amp;b); // copy ctor
    B &amp;operator =(B &amp;b); // assignment operator
};

foo(const A &amp;a) {
    float f = 0.0f;
    B b = a.getB();
}
</code></pre>
<p>Wenn in foo() nun die zweite Zeile ausgeführt wird, dann wird der Wert von f mit Müll überschrieben und beim Aussteigen aus der Funktion gibt es den Fehler, dass um f der Stack korrumpiert sei (völlig zurecht). Ich habe das Überschreiben genau auf die Initialisierung der map im Copy-Constructor von B, der in getB() aufgerufen wird, zurückverfolgt. Nun liegt in foo() b im Speicher genau vor f, und da scheint irgendwie aus b hinten was überzulaufen und f zu überschreiben.</p>
<p>Das ist mir wie gesagt völlig unverständlich. Ein Objekt kann ja nicht einfach seine Größe verändern, und die Map dürfte auch ihre Daten nicht einfach so in schon benutztem Speicher ablegen.</p>
<p>Ich habe das Problem vorerst umgangen, indem ich b auf dem Heap allokiere, aber das kommt mir wie ein übler Workaround vor. Ich würde gerne wissen, warum sich das hier so verhält.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/246814/std-map-im-copy-constructor-überschreibt-daten</link><generator>RSS for Node</generator><lastBuildDate>Thu, 17 Sep 2026 13:52:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/246814.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 02 Aug 2009 10:27:15 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 02 Aug 2009 10:27:15 GMT]]></title><description><![CDATA[<p>Ich bin gestern auf ein mir unerklärliches Problem gestoßen. Ich habe ein Design der folgenden Art:</p>
<pre><code class="language-cpp">class A {
private:
    B b;
public:
    B getB() { return b; }
};

class B {
private:
    std::map&lt;int, float*&gt; map;
public:
    B(B &amp;b); // copy ctor
    B &amp;operator =(B &amp;b); // assignment operator
};

foo(const A &amp;a) {
    float f = 0.0f;
    B b = a.getB();
}
</code></pre>
<p>Wenn in foo() nun die zweite Zeile ausgeführt wird, dann wird der Wert von f mit Müll überschrieben und beim Aussteigen aus der Funktion gibt es den Fehler, dass um f der Stack korrumpiert sei (völlig zurecht). Ich habe das Überschreiben genau auf die Initialisierung der map im Copy-Constructor von B, der in getB() aufgerufen wird, zurückverfolgt. Nun liegt in foo() b im Speicher genau vor f, und da scheint irgendwie aus b hinten was überzulaufen und f zu überschreiben.</p>
<p>Das ist mir wie gesagt völlig unverständlich. Ein Objekt kann ja nicht einfach seine Größe verändern, und die Map dürfte auch ihre Daten nicht einfach so in schon benutztem Speicher ablegen.</p>
<p>Ich habe das Problem vorerst umgangen, indem ich b auf dem Heap allokiere, aber das kommt mir wie ein übler Workaround vor. Ich würde gerne wissen, warum sich das hier so verhält.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1753922</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1753922</guid><dc:creator><![CDATA[David Schneider]]></dc:creator><pubDate>Sun, 02 Aug 2009 10:27:15 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 02 Aug 2009 10:37:58 GMT]]></title><description><![CDATA[<p>Zeig doch mal bitte deine Implementierung des copy-CTors und des operator=.<br />
Du übergibst denen nicht-const-Referenzen. Ist eigentlich unnötig, willst ja das kopierte Objekt (hoffentlich) nicht verändern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1753929</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1753929</guid><dc:creator><![CDATA[Kopist]]></dc:creator><pubDate>Sun, 02 Aug 2009 10:37:58 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 02 Aug 2009 14:43:47 GMT]]></title><description><![CDATA[<p>Das Beispiel sollte eigentlich in Zeile 18 einen Compilerfehler verursachen, weil kein passender Copy-ctor existiert (wobei nicht alle Compiler das im Falle von copy-elision überprüfen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1754019</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1754019</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sun, 02 Aug 2009 14:43:47 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 02 Aug 2009 14:51:32 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a>: Der normale Copy-Ctor wird doch immer noch generiert. Ein Konstruktor, der eine non-const Referenz nimmt, gilt imho als normaler Konstruktor und nicht als Kopierkonstruktor. Der Kompiler erstellt also keinen Default-Ctor. Den Kopierkonstruktor erzeugt er aber noch.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1754022</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1754022</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Sun, 02 Aug 2009 14:51:32 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 02 Aug 2009 14:57:20 GMT]]></title><description><![CDATA[<p>Don06 schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a>: Der normale Copy-Ctor wird doch immer noch generiert. Ein Konstruktor, der eine non-const Referenz nimmt, gilt imho als normaler Konstruktor und nicht als Kopierkonstruktor. Der Kompiler erstellt also keinen Default-Ctor. Den Kopierkonstruktor erzeugt er aber noch.</p>
</blockquote>
<p>12.8/2</p>
<blockquote>
<p>A non-template constructor for class X is a copy constructor if its first parameter is of type X&amp;, const X&amp;, volatile X&amp; or const volatile X&amp;, and either there are no other parameters or else all other parameters have default arguments (8.3.6).106) [Example: X::X(const X&amp;) and X::X(X&amp;, int=1) are copy constructors.</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1754025</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1754025</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sun, 02 Aug 2009 14:57:20 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 02 Aug 2009 15:33:06 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6642">@camper</a>: Oh, das wusste ich nicht. Aber ist dann der Fehler im obigen Fall nur durch einen Compiler-Fehler zu erklären?</p>
<p>Ich habe mal ein lauffähiges Programm erstellt. Der Fehler tritt bei mir nicht auf.</p>
<pre><code class="language-cpp">#include &lt;map&gt;
#include &lt;iostream&gt;

class B {
private:
    std::map&lt;int, float*&gt; map;
public:
	B() {}
    B(const B &amp;b) // copy ctor
		: map(b.map)
	{ }
};

class A {
private:
    B b;
public:
    B getB() const { return b; }
};

void foo(const A &amp;a) 
{
    float f = 0.0f;
    B b = a.getB();
	std::cout &lt;&lt; f;
}

int main()
{
	foo(A());
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1754048</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1754048</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Sun, 02 Aug 2009 15:33:06 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Mon, 03 Aug 2009 08:01:54 GMT]]></title><description><![CDATA[<p>Hallo David Schneider,</p>
<p>der Fehler scheint nicht direkt in dem gezeigten Code zu liegen. Allerdings fällt auf das Du einen <strong>Zeiger</strong> auf float in der Map speicherst. Da gibt es viele mögliche Fehlerquellen. Kann es sein, das Du in einer anderen Funktion sinngemäß folgendes machst?</p>
<pre><code class="language-cpp">void bar(B &amp;b)
{
    float f = 0.0f;
    b[5] = &amp;f;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1754369</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1754369</guid><dc:creator><![CDATA[DJohn@work]]></dc:creator><pubDate>Mon, 03 Aug 2009 08:01:54 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Mon, 03 Aug 2009 10:37:51 GMT]]></title><description><![CDATA[<p>DJohn@work schrieb:</p>
<blockquote>
<p>...Allerdings fällt auf das Du einen <strong>Zeiger</strong> auf float in der Map speicherst. ...</p>
</blockquote>
<p>Das ist mir auch als Erstes aufgefallen.<br />
Eine andere dadurch entstehende Fehlerquelle hat bereits &quot;Kopist&quot; angemerkt: Klassen mit Zeigern zu kopieren ist nicht trivial - und es wird bei std::map garantiert reichlich genutzt.<br />
Dieses Problem löst man übrigens nicht durch Ignorieren (weder durch mentales noch durch programmiertechnisches <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>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1754440</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1754440</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Mon, 03 Aug 2009 10:37:51 GMT</pubDate></item><item><title><![CDATA[Reply to std::map im Copy-Constructor überschreibt Daten on Sun, 09 Aug 2009 15:07:27 GMT]]></title><description><![CDATA[<p>Simon2 schrieb:</p>
<blockquote>
<p>Dieses Problem löst man übrigens nicht durch Ignorieren (weder durch mentales noch durch programmiertechnisches <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>
</blockquote>
<p>Weswegen es dieses Topic gibt. <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="😉"
    /> Ich habe das Problem aber durch eine neue Gestaltung des verwendenden Codes beseitigen können. Ich weiß es nicht mit Sicherheit, aber ich vermute den Fehler bei meinem eigenen Code in der Klasse, der eben jene Zeiger auf floats in der Map mit Arrays füllte und diese wieder löschte. Gut möglich, dass dabei eine Unvollständigkeit passiert ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1757909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1757909</guid><dc:creator><![CDATA[David Schneider]]></dc:creator><pubDate>Sun, 09 Aug 2009 15:07:27 GMT</pubDate></item></channel></rss>