<?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[Konstante Variablen werden verändert]]></title><description><![CDATA[<p>Hi,<br />
Ich schreibe gerade eine mathematische Klasse für einen Vektor.<br />
Diese Klasse nutzte VORHER ein Template der Art</p>
<pre><code class="language-cpp">template &lt;class typeOfVariable, unsigned int numElements&gt;
</code></pre>
<p>um statisch Speicherplatz für jedes Element zu vergeben. Alles funktionierte wunderbar.</p>
<p>Aus verschiedenen Gründen musste ich die Klasse derart umschreiben, dass sie nun Ihren Speicher dynamisch reserviert:</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
class Vector
{
    private:
    typeOfVariable* vectorElement;
    unsigned int    numElements;
</code></pre>
<p>Zum Ansprechen von Elementen wird der Operator [] überladen:</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
typeOfVariable&amp; Vector&lt;typeOfVariable&gt;::operator[] (const unsigned int index) const
{
    //Out of range!
    assert(index &lt; numElements);
    return vectorElement[index];
}
</code></pre>
<p>Ebenfalls überladen wird der Operator = :</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
Vector&lt;typeOfVariable&gt; Vector&lt;typeOfVariable&gt;::operator=  (const Vector&lt;typeOfVariable&gt; v)
{
    //Both vectors have to be of equal dimension
    if (numElements != v.getDimension())
    {
        numElements = v.getDimension();
        delete[] vectorElement;
        vectorElement = new typeOfVariable[numElements];
    }
    //Assign values to this vector
    for (unsigned int i=0; i&lt;numElements; i++)
        vectorElement[i] = v[i];

    return *this;
}
</code></pre>
<p>Das Zuweisen von Werten (doubles) funktioniert prima. Hier zum Beispiel ein Vektor mit drei Elementen und den Werten 2, 2, 8 sowie 1, 2, 3:</p>
<pre><code class="language-cpp">Vector&lt;double&gt; vec(3, 2.0, 2.0, 8.0);
Vector&lt;double&gt; vec2(3, 1.0, 2.0, 3.0);
</code></pre>
<p>Sobald ich aber schreibe...</p>
<pre><code class="language-cpp">vec = vec2;
</code></pre>
<p>...erhalte ich seltsame Werte, die danach riechen, dass irgendwo in fremde Speicherbereiche hineingelesen / geschrieben wird:</p>
<blockquote>
<p>vec: 1.35943e-305 / 2 / 3<br />
vec2: 0 / 0 / 0</p>
</blockquote>
<p>Woran kann das liegen? Warum wird auch vec2 verändert? Die Variable ist doch als const deklariert worden.</p>
<p>Danke für eure Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/294095/konstante-variablen-werden-verändert</link><generator>RSS for Node</generator><lastBuildDate>Sun, 16 Aug 2026 01:05:00 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/294095.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 17 Oct 2011 19:20:12 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Mon, 17 Oct 2011 19:21:37 GMT]]></title><description><![CDATA[<p>Hi,<br />
Ich schreibe gerade eine mathematische Klasse für einen Vektor.<br />
Diese Klasse nutzte VORHER ein Template der Art</p>
<pre><code class="language-cpp">template &lt;class typeOfVariable, unsigned int numElements&gt;
</code></pre>
<p>um statisch Speicherplatz für jedes Element zu vergeben. Alles funktionierte wunderbar.</p>
<p>Aus verschiedenen Gründen musste ich die Klasse derart umschreiben, dass sie nun Ihren Speicher dynamisch reserviert:</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
class Vector
{
    private:
    typeOfVariable* vectorElement;
    unsigned int    numElements;
</code></pre>
<p>Zum Ansprechen von Elementen wird der Operator [] überladen:</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
typeOfVariable&amp; Vector&lt;typeOfVariable&gt;::operator[] (const unsigned int index) const
{
    //Out of range!
    assert(index &lt; numElements);
    return vectorElement[index];
}
</code></pre>
<p>Ebenfalls überladen wird der Operator = :</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
Vector&lt;typeOfVariable&gt; Vector&lt;typeOfVariable&gt;::operator=  (const Vector&lt;typeOfVariable&gt; v)
{
    //Both vectors have to be of equal dimension
    if (numElements != v.getDimension())
    {
        numElements = v.getDimension();
        delete[] vectorElement;
        vectorElement = new typeOfVariable[numElements];
    }
    //Assign values to this vector
    for (unsigned int i=0; i&lt;numElements; i++)
        vectorElement[i] = v[i];

    return *this;
}
</code></pre>
<p>Das Zuweisen von Werten (doubles) funktioniert prima. Hier zum Beispiel ein Vektor mit drei Elementen und den Werten 2, 2, 8 sowie 1, 2, 3:</p>
<pre><code class="language-cpp">Vector&lt;double&gt; vec(3, 2.0, 2.0, 8.0);
Vector&lt;double&gt; vec2(3, 1.0, 2.0, 3.0);
</code></pre>
<p>Sobald ich aber schreibe...</p>
<pre><code class="language-cpp">vec = vec2;
</code></pre>
<p>...erhalte ich seltsame Werte, die danach riechen, dass irgendwo in fremde Speicherbereiche hineingelesen / geschrieben wird:</p>
<blockquote>
<p>vec: 1.35943e-305 / 2 / 3<br />
vec2: 0 / 0 / 0</p>
</blockquote>
<p>Woran kann das liegen? Warum wird auch vec2 verändert? Die Variable ist doch als const deklariert worden.</p>
<p>Danke für eure Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132648</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132648</guid><dc:creator><![CDATA[Mercator]]></dc:creator><pubDate>Mon, 17 Oct 2011 19:21:37 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Mon, 17 Oct 2011 21:54:04 GMT]]></title><description><![CDATA[<p>Wie sieht dein Copy-Konstruktor aus?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132690</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132690</guid><dc:creator><![CDATA[hmpf]]></dc:creator><pubDate>Mon, 17 Oct 2011 21:54:04 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Mon, 17 Oct 2011 21:57:51 GMT]]></title><description><![CDATA[<p>Hmm, eine Klasse namens Vector die sich selbst dynamisch Speicher reserviert...</p>
<p>War da nicht irgendwas? Hatte glaube ich irgendwas mit der Standardbibliothek zu tun...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132692</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Mon, 17 Oct 2011 21:57:51 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 00:42:03 GMT]]></title><description><![CDATA[<p>Mercator schrieb:</p>
<blockquote>
<p>Sobald ich aber schreibe...</p>
<pre><code class="language-cpp">vec = vec2;
</code></pre>
<p>...erhalte ich seltsame Werte,</p>
</blockquote>
<p>Dein Code sieht eigentlich richtig aus.<br />
Sicher, daß er bei</p>
<pre><code class="language-cpp">vec = vec2;
</code></pre>
<p>passiert und nicht bei</p>
<pre><code class="language-cpp">vec = vec;
</code></pre>
<p>?<br />
Gegen Selbstzuweisung ist er nämlich nicht sicher. Dein Code würde richtig geil abkeckern, fast immer laufen, sagen wir mal 20000 zu 1 bringen, 20000 Läufe klappen und einer nicht. Also gerade der Lauf, wo der Kunde das erste mal damit im Fernsehen zu sehen ist. Oder mit netter Debug-Bibliothek auch öfter oder jesesmal. Das Problem hier wäre, daß Du vec.zeug erst deleten würdest, um es dann nach dem neuen vec.zeug zu kopieren. Geht natürlich nicht, weil es schon deleted wurde.<br />
Früher verhinderte man das mit einem if(&amp;v==this) return; als erste Zeile.<br />
Jetzt nimmt man das Copy&amp;Swap-Idiom, weil es darüberhinaus noch exceptionsicher ist. Und eigentlich auch einfacher irgendwie.</p>
<p>Das ist aber kein Fehler, der oft sichtbar wird, weil eine Selbstzuweisung im Anwendungscode sehr selten ist. Eigentlich nur, wenn der Anwendungscodierer umständlich ist. Oder ganz selten manchmal, wenn... (geschätzt, bei mir zweimal in drei Jahren) (strukturierte Programmierer ohne break, goto und continue vermutlich auch häufiger, bis zu einmal im Monat, frei grob geschätzt).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132725</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132725</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 18 Oct 2011 00:42:03 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 06:55:25 GMT]]></title><description><![CDATA[<p>Hi,<br />
Danke an hmpf und volkard.</p>
<p>Ich hatte keinen Copy-Konstruktor. Sobald ich ihn implementiert hatte, funktionierte bereits das Beispiel.</p>
<p>So sieht er aus:</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
Vector&lt;typeOfVariable&gt;::Vector(const Vector&lt;typeOfVariable&gt;&amp; v)
{
      numElements   = v.getDimension();
      vectorElement = new typeOfVariable[numElements];

      for(unsigned int i=0;i&lt;numElements;i++)
         vectorElement[i]=v[i];
};
</code></pre>
<p>Außerdem verwende ich nun das Copy&amp;Swap-Idiom:</p>
<pre><code class="language-cpp">template&lt;class typeOfVariable&gt;
Vector&lt;typeOfVariable&gt; Vector&lt;typeOfVariable&gt;::operator=  (const Vector&lt;typeOfVariable&gt; v)
{
    Vector&lt;typeOfVariable&gt; temp(v); // Copy constructor
    temp.swap(*this);
    return *this;
}

template&lt;class typeOfVariable&gt;
void Vector&lt;typeOfVariable&gt;::swap(Vector&lt;typeOfVariable&gt;&amp; v)
{
      std::swap(numElements, v.numElements);
      std::swap(vectorElement, v.vectorElement);
};
</code></pre>
<p>Mein Code funktioniert jetzt. Vielen Dank!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132737</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132737</guid><dc:creator><![CDATA[Mercator]]></dc:creator><pubDate>Tue, 18 Oct 2011 06:55:25 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 07:36:39 GMT]]></title><description><![CDATA[<p>Das hättest Du auch einfacher haben können:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
class vec
{
  std::vector&lt;T&gt; coeffs_;
public:
  u.s.w.
};
</code></pre>
<p>(ohne Zuweisungsoperator, Kopierkonstruktor und Destruktor selbst definieren zu müssen)</p>
<p>Wie hast Du denn Konstruktor gebaut, der die Koeffizienten entgegen nimmt? Ich hoffe, der sieht nicht so aus:</p>
<pre><code class="language-cpp">vec::vec(int dim,...);
</code></pre>
<p>Da geht nämlich leider die Typinformation verloren (so dass der Compiler das nicht prüfen kann). Du erwartest sicherlich die Typen T. Aufrufen kannst du den aber leider mit beliebigen Argumenten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132743</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132743</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 18 Oct 2011 07:36:39 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 07:43:16 GMT]]></title><description><![CDATA[<p>Dass du da Probleme bekommst, liegt wohl daran, dass du dem operator= einen Value mitgibst. So wie beim Copy-CTor sollte das eine const-Referenz sein (das const steht ja schon da, nur das &quot;&amp;&quot; fehlt). Dadurch wird vor dem Zuweisen per operator= erst eine Kopie gezogen - und HIER geht es dann schief.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132747</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132747</guid><dc:creator><![CDATA[Referend Opa]]></dc:creator><pubDate>Tue, 18 Oct 2011 07:43:16 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 08:23:03 GMT]]></title><description><![CDATA[<p>Referend Opa schrieb:</p>
<blockquote>
<p>So wie beim Copy-CTor sollte das eine const-Referenz sein</p>
</blockquote>
<p>Warum? Manchmal finde ich so'was wie</p>
<pre><code class="language-cpp">Typ&amp; Typ::operator=(Typ lokale_kopie)
{
  this-&gt;swap(lokale_kopie);
  return *this;
}
</code></pre>
<p>total praktisch. Das könnte man hier auch machen. Aber, wie gesagt, noch besser finde ich es, wenn ich die speziellen Funktionen gar nicht selbst schreiben muss. Das ist dann weniger fehleranfällig und kürzer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132761</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132761</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 18 Oct 2011 08:23:03 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 08:31:31 GMT]]></title><description><![CDATA[<p>aber dadurch kam sicher sein Problem zustande, da er für die lokale Kopie keinen Copy-CTor hatte.</p>
<p>greetz KN4CK3R</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132764</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132764</guid><dc:creator><![CDATA[KN4CK3R]]></dc:creator><pubDate>Tue, 18 Oct 2011 08:31:31 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 09:18:29 GMT]]></title><description><![CDATA[<p>Ja sicher. Ich konnte das nur so als generelle Aussage nicht stehen lassen. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2132776</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132776</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 18 Oct 2011 09:18:29 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 09:28:43 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Ja sicher. Ich konnte das nur so als generelle Aussage nicht stehen lassen. <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>
</blockquote>
<p>War doch gar nicht &quot;generell&quot;. Ich fang an mit &quot;dass du da&quot;, was sich auf seinen Kontext bezieht. Und der letzte Satz sagt auch eindeutig, dass so erst noch die Kopie gezogen wird, was bei ihm das Problem auslöst.<br />
Eine generell fordernde Aussage wäre &quot;op= muss immer eine const-Referenz übergeben bekommen&quot;, und das lese ich aus meinem obigen Beitrag nicht raus.</p>
<p>Seine aktuelle Lösung verwendet zwar Copy&amp;Swap, aber es werden 2 Kopien gezogen (wäre vllt. besser gewesen ihn hierauf hinzuweisen, als auf irgend welchen Formulierungen und Generalisierungen rumzureiten)! Einmal in den const-Parameter der Funktion, und dann nochmal eine in der Funktion. Wenn du deinen op= schon per Copy&amp;Swap implementierst, dann entweder wieder per constref übergeben und Kopie in der Funktion oder kein const-Value als Parameter sondern direkt so wie es Krümelkacker gezeigt hat. Ersteres hat den Vorteil (wenn man so will), dass die Implementierung nicht schon durch die Signatur ersichtlich ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132780</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132780</guid><dc:creator><![CDATA[Referend Opa]]></dc:creator><pubDate>Tue, 18 Oct 2011 09:28:43 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 10:15:13 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Das hättest Du auch einfacher haben können:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
class vec
{
  std::vector&lt;T&gt; coeffs_;
public:
  u.s.w.
};
</code></pre>
<p>(ohne Zuweisungsoperator, Kopierkonstruktor und Destruktor selbst definieren zu müssen)</p>
</blockquote>
<p>Ja, ok. Besonders jetzt, wo der Vektor dynamisch geworden ist, ist es wirklich kürzer. Hab es geändert.<br />
Die Thematik mit dem Copy-Konstruktor kannte ich aber noch nicht. Also gut, dass das Problem mal auftauchte <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>krümelkacker schrieb:</p>
<blockquote>
<p>Wie hast Du denn Konstruktor gebaut, der die Koeffizienten entgegen nimmt? Ich hoffe, der sieht nicht so aus:</p>
<pre><code class="language-cpp">vec::vec(int dim,...);
</code></pre>
<p>Da geht nämlich leider die Typinformation verloren (so dass der Compiler das nicht prüfen kann). Du erwartest sicherlich die Typen T. Aufrufen kannst du den aber leider mit beliebigen Argumenten.</p>
</blockquote>
<p>Hatte schon überlegt, ob ich ihn rausnehme oder dennoch verwende. Man kann schließlich auch schlecht prüfen, ob die richtige Anzahl an Argumenten angegeben wurde. Sind es zu wenig, liest er in fremde Speicherbereiche hinein.</p>
<p>Eine Zeile zum initialisieren von einem Vektor ist aber einfach praktisch.</p>
<p>Als nächstes wollte ich eine Matrix implementieren, die aus Spaltenvektoren besteht. Jetzt könnte ich doch wieder den std::vector nehmen und meine mathematischen Vektoren darin speichern, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132786</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132786</guid><dc:creator><![CDATA[Mercator]]></dc:creator><pubDate>Tue, 18 Oct 2011 10:15:13 GMT</pubDate></item><item><title><![CDATA[Reply to Konstante Variablen werden verändert on Tue, 18 Oct 2011 10:15:27 GMT]]></title><description><![CDATA[<p>edit: Hat sich inzwischen erledigt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2132789</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2132789</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 18 Oct 2011 10:15:27 GMT</pubDate></item></channel></rss>