<?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[Mal wieder ein Strinklassen Problem...]]></title><description><![CDATA[<p>So ich habe seit ich das letzte mal hier gepostet habe mich belesen und diverse Dinge überarbeitet... Nur habe ich jetzt einen Fehler, wenn ich dem String erneut einen neuen String zuweise:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;cstdio&gt;

#define Debug(x) cout &lt;&lt; x &lt;&lt; endl;

using namespace std;

class String
{
private:
    char* data;

    void copy(char* dest, const char* source)
    {
        while (((*dest++) = (*source++)));
    };

    void createMemory(int length)
    {
        Debug(&quot;New Memory length(&quot; &lt;&lt; length &lt;&lt; &quot;)&quot;)
        if(length &lt;= 0)
            length = 1;

        data = new char[length];
        if (data == NULL)
            throw MemoryException();

        if (length &gt; 0)
            data[length - 1] = '\0';
    }

public:
    String() : data(NULL)
    {
        createMemory(1);
    }
    String(const char* string) : data(NULL)
    {
        Debug(&quot;Create Memory for charArray(&quot;&lt;&lt; string &lt;&lt;&quot;)&quot;);
        createMemory(getSize(string)+1);
        copy(data, string);
        Debug(&quot;Data: &quot; &lt;&lt; data)
    };
    String(String const&amp; other) : data(NULL)
    {
        Debug(&quot;Create Memory for string(&quot;&lt;&lt; other &lt;&lt;&quot;)&quot;);
        createMemory(other.getSize()+1);
        copy(this-&gt;data, other.data);
    };
    ~String()
    {
        // Wenn Daten nicht existieren
        // oder Länge 0 ist, löschen nicht notwendig
        // Verhindert Memory (double free) corruption
        // dirty hack...
        if(data != NULL &amp;&amp; getSize() != 0){
            delete [] data;
        }
    };

    int getSize() const
    {
        return getSize(data);
    };

    int getSize(const char* ca) const
    {
        int i = 0;
        if (ca != NULL)
        {
            for (i = 0; *ca++; i++);
        }
        return i;
    }

    void append(String string)
    {
        // Neue Länge ermitteln
        int fullLength = getSize() + string.getSize();

        // Temporären String erstellen
        char* tmp = new char[fullLength+1];

        // Beide Strings in den temporären string schreiben
        for (int i = 0; i &lt; getSize(); i++)
        {
            tmp[i] = data[i];
        }
        for (int i = 0; i &lt; string.getSize(); i++)
        {
            tmp[getSize()+i] = string.data[i];
        }
        // Nullterminator anhängen
        tmp[fullLength] = '\0';

        // Daten löschen und neu initalisieren
        delete [] data;
        data = new char[fullLength+1];

        // Daten rüber kopieren
        copy(data, tmp);

        // Temporären String löschen
        delete [] tmp;
    }

    String operator + (String s)
    {
        append(s);
        return *this;
    }
    String operator += (String s)
    {
        append(s);
        return *this;
    }

    const char* c_str() const
    {
        return data;
    }

    operator char * ()
    {
        if ( data == NULL )
        {
            createMemory(1);
        }
        Debug(&quot;Convert to charArray: &quot; &lt;&lt; data);
        return data;
    }

    operator const char * () const
    {
        return c_str();
    }

    int toInteger(){
        std::stringstream s(data);
        int i = 0;
        s &gt;&gt; i;
        return i;
    }

};

int main()
{
    String s = &quot;Bla&quot;;

    s = &quot;123&quot;;
    cout &lt;&lt; s &lt;&lt; endl;
    cout &lt;&lt; s.toInteger() &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Das seltsame es wird alles wunderbar zugewiesen und so weiter und sofort aber wenn ich dann versuche auf die Daten zuzugreifen sind die auf einmal weg? Wo liegt der Fehler ich suche schon seit mehreren Stunden, finde ihn aber einfach nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>Bin dankbar für jede Hilfe.</p>
<p>Außerdem wollte ich darauf hinweisen, das das kopieren und die Längenbestimmung nach Vorgabe selber programmiert werden müssen, daher nicht die strlen oder strcpy Funktionen der cstring libary.</p>
<p>Danke,<br />
Blackskyliner.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/263368/mal-wieder-ein-strinklassen-problem</link><generator>RSS for Node</generator><lastBuildDate>Sat, 05 Sep 2026 19:26:56 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/263368.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 19 Mar 2010 15:49:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 15:49:07 GMT]]></title><description><![CDATA[<p>So ich habe seit ich das letzte mal hier gepostet habe mich belesen und diverse Dinge überarbeitet... Nur habe ich jetzt einen Fehler, wenn ich dem String erneut einen neuen String zuweise:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;cstdio&gt;

#define Debug(x) cout &lt;&lt; x &lt;&lt; endl;

using namespace std;

class String
{
private:
    char* data;

    void copy(char* dest, const char* source)
    {
        while (((*dest++) = (*source++)));
    };

    void createMemory(int length)
    {
        Debug(&quot;New Memory length(&quot; &lt;&lt; length &lt;&lt; &quot;)&quot;)
        if(length &lt;= 0)
            length = 1;

        data = new char[length];
        if (data == NULL)
            throw MemoryException();

        if (length &gt; 0)
            data[length - 1] = '\0';
    }

public:
    String() : data(NULL)
    {
        createMemory(1);
    }
    String(const char* string) : data(NULL)
    {
        Debug(&quot;Create Memory for charArray(&quot;&lt;&lt; string &lt;&lt;&quot;)&quot;);
        createMemory(getSize(string)+1);
        copy(data, string);
        Debug(&quot;Data: &quot; &lt;&lt; data)
    };
    String(String const&amp; other) : data(NULL)
    {
        Debug(&quot;Create Memory for string(&quot;&lt;&lt; other &lt;&lt;&quot;)&quot;);
        createMemory(other.getSize()+1);
        copy(this-&gt;data, other.data);
    };
    ~String()
    {
        // Wenn Daten nicht existieren
        // oder Länge 0 ist, löschen nicht notwendig
        // Verhindert Memory (double free) corruption
        // dirty hack...
        if(data != NULL &amp;&amp; getSize() != 0){
            delete [] data;
        }
    };

    int getSize() const
    {
        return getSize(data);
    };

    int getSize(const char* ca) const
    {
        int i = 0;
        if (ca != NULL)
        {
            for (i = 0; *ca++; i++);
        }
        return i;
    }

    void append(String string)
    {
        // Neue Länge ermitteln
        int fullLength = getSize() + string.getSize();

        // Temporären String erstellen
        char* tmp = new char[fullLength+1];

        // Beide Strings in den temporären string schreiben
        for (int i = 0; i &lt; getSize(); i++)
        {
            tmp[i] = data[i];
        }
        for (int i = 0; i &lt; string.getSize(); i++)
        {
            tmp[getSize()+i] = string.data[i];
        }
        // Nullterminator anhängen
        tmp[fullLength] = '\0';

        // Daten löschen und neu initalisieren
        delete [] data;
        data = new char[fullLength+1];

        // Daten rüber kopieren
        copy(data, tmp);

        // Temporären String löschen
        delete [] tmp;
    }

    String operator + (String s)
    {
        append(s);
        return *this;
    }
    String operator += (String s)
    {
        append(s);
        return *this;
    }

    const char* c_str() const
    {
        return data;
    }

    operator char * ()
    {
        if ( data == NULL )
        {
            createMemory(1);
        }
        Debug(&quot;Convert to charArray: &quot; &lt;&lt; data);
        return data;
    }

    operator const char * () const
    {
        return c_str();
    }

    int toInteger(){
        std::stringstream s(data);
        int i = 0;
        s &gt;&gt; i;
        return i;
    }

};

int main()
{
    String s = &quot;Bla&quot;;

    s = &quot;123&quot;;
    cout &lt;&lt; s &lt;&lt; endl;
    cout &lt;&lt; s.toInteger() &lt;&lt; endl;

    return 0;
}
</code></pre>
<p>Das seltsame es wird alles wunderbar zugewiesen und so weiter und sofort aber wenn ich dann versuche auf die Daten zuzugreifen sind die auf einmal weg? Wo liegt der Fehler ich suche schon seit mehreren Stunden, finde ihn aber einfach nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>Bin dankbar für jede Hilfe.</p>
<p>Außerdem wollte ich darauf hinweisen, das das kopieren und die Längenbestimmung nach Vorgabe selber programmiert werden müssen, daher nicht die strlen oder strcpy Funktionen der cstring libary.</p>
<p>Danke,<br />
Blackskyliner.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871357</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871357</guid><dc:creator><![CDATA[Blackskyliner]]></dc:creator><pubDate>Fri, 19 Mar 2010 15:49:07 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 15:57:36 GMT]]></title><description><![CDATA[<p>Das Programm ist ziemlich lang und komplex. Um darin Fehler zu finden, eignet sich ideal der Einsatz eines Debuggers. Damit wirst du sicherlich schnell fündig, sobald du gelernt hast damit umzugehen. Und wenn du es erst einmal kannst, ist das ein unschätzbares Werkzeug für die Zukunft.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871363</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871363</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 19 Mar 2010 15:57:36 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 16:03:56 GMT]]></title><description><![CDATA[<p>Ich bin es ja schon mit dem Code::Blocks Debugger durch gegangen und hab auch da entsprechend nicht wirklich komfortable Möglichkeiten das irgendwie &quot;toll&quot; zu überwachen... (Anders ausgedrückt ich hab den Fehler dadurch nicht wirklich gefunden) Das einzige was &quot;besser&quot; wäre, würde der Einsatz des Visual Studios Debuggers sein... Nur das ich da erstmal ewig runter laden muss bei meiner Anbindung....</p>
<p>Ich dachte es wäre irgend ein Simpler schon 100 fach besprochener Fehler, sodass ich vielleicht von den Erfahrungen der Mitglieder dieses Forums profitieren kann.</p>
<p>Aber da werde ich mich halt nochmal mit dem gdb dahinter klemmen und schauen ob mir vielleicht doch noch irgendwas auffällt.</p>
<p>Trotzdem 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>
<p>Blackskyliner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871368</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871368</guid><dc:creator><![CDATA[Blackskyliner]]></dc:creator><pubDate>Fri, 19 Mar 2010 16:03:56 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 16:08:08 GMT]]></title><description><![CDATA[<p>Blackskyliner schrieb:</p>
<blockquote>
<p>Ich dachte es wäre irgend ein Simpler schon 100 fach besprochener Fehler, sodass ich vielleicht von den Erfahrungen der Mitglieder dieses Forums profitieren kann.</p>
</blockquote>
<p>Der Fehler riecht nach einem falsch zugewiesenen Pointer. Aber an welcher Stelle jetzt genau, dafür müsste ich erstmal das ganze Programm nachvollziehen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871373</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871373</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 19 Mar 2010 16:08:08 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 16:13:28 GMT]]></title><description><![CDATA[<p>operator+ ist falsch definiert. Passiert das bei der Konkatenation?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871375</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871375</guid><dc:creator><![CDATA[witte]]></dc:creator><pubDate>Fri, 19 Mar 2010 16:13:28 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 16:24:41 GMT]]></title><description><![CDATA[<p>witte schrieb:</p>
<blockquote>
<p>operator+ ist falsch definiert. Passiert das bei der Konkatenation?</p>
</blockquote>
<p>Nee erst nach dem erneutem zuweisen, das appenden eines Strings funktioniert einwandfrei...</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/19375">@SeppJ</a>: Ja so was in der Art denk ich auch... Aber eigentlich müsste alles hin haun... Nach dem Konstruktor sind die Daten ja alle sogar DA die existieren nach dem Prozess aber kaum will ich von außen drauf zugreifen sind die Daten auf einmal leer...</p>
<p>Blackskyliner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871380</guid><dc:creator><![CDATA[Blackskyliner]]></dc:creator><pubDate>Fri, 19 Mar 2010 16:24:41 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Fri, 19 Mar 2010 16:46:12 GMT]]></title><description><![CDATA[<p>Kein Zuweisungsoperator definiert ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871382</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871382</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Fri, 19 Mar 2010 16:46:12 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Sat, 20 Mar 2010 12:11:10 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>Kein Zuweisungsoperator definiert ...</p>
</blockquote>
<p>Ganz zu schweigen von fehlender Exceptionsicherheit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871593</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Sat, 20 Mar 2010 12:11:10 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Sat, 20 Mar 2010 19:49:55 GMT]]></title><description><![CDATA[<p>Inwiefern Exceptionsicherheit?<br />
Was kann oder muss ich denn machen damit es &quot;sicher&quot; ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871781</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871781</guid><dc:creator><![CDATA[Blackskyliner]]></dc:creator><pubDate>Sat, 20 Mar 2010 19:49:55 GMT</pubDate></item><item><title><![CDATA[Reply to Mal wieder ein Strinklassen Problem... on Sat, 20 Mar 2010 23:04:49 GMT]]></title><description><![CDATA[<p><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="😃"
    /> genau so hab ich auch angefangen <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>Zur Erklärung:<br />
Bei s = &quot;123&quot;; würde der Compiler nach einem operator=(const char <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="😉"
    /> suchen, den du aber nicht implementiert hast. Weil du aber auch keinen operator=(const String &amp;) bereitgestellt hast, hat der Compiler diesen automatisch erstellt. Nun weis der Compiler, dass er aus &quot;123&quot; ein neues String-Objekt erzeugen kann und tut das auch. Dieses temporäre String-Objekt wird jetzt über den default-operator=(const String &amp;) an s zugewiesen, aber dieser böse operator kopiert nur alle Daten-Member vom temporären String-Objekt über s drüber. Und das ist das Problem: Jetzt teilen sich beide Objekte den gleichen Pointer auf das char-array. Das temporäre String-Objekt wird nach diesem Einsatz zerstört (-&gt; Destruktor) und löscht das char-array. Somit hat s einen pointer auf nicht mehr vorhandene Daten. Sobald du also irgend wie mit s arbeitest kracht es.</p>
<pre><code class="language-cpp">String&amp; operator=(const String &amp; r)
{
  if(this != &amp;r)
  {
    int sz = r.getSize();
    char * tmp = new char[sz + 1];
    memcpy(tmp, r.data, sz);
    tmp[sz] = 0;
    delete [] this-&gt;data;
    this-&gt;data = tmp;
  }
  return *this;
}
</code></pre>
<p>Etwas Ähnliches kannst du auch bei einem String&amp; operator=(const char * str) schreiben, dann braucht der Compiler kein temporäres Objekt erzeugen, dass er dann sowieso nach dem Kopieren gleich wieder zerstören muss.</p>
<p>Da gibt es ja diese Regel, dass wenn ein Objekt entweder einen Copy-Constructor oder einen Assignment-operator oder einen Destructor braucht, automatisch auch die beiden anderen notwendig sind (meistens zumindest).</p>
<p>Die append Methode ist zB. nicht Exception-sicher, weil zuerst delete [] data aufgerufen wird, und danach data = new char[fullLength + 1]. Wenn jetzt nicht mehr genug Speicher frei ist, löst new die Exception aus, während data auf ungültige Daten verweist. Die Exception bewirkt dann, dass dein String Objekt zerstört wird und im Destruktor rufst du damit erneut delete[] auf bereits gelöschte Daten auf -&gt; crash.<br />
Schreib doch anstatt data = new char[fullLength + 1] einfach data = tmp; fertig. Es ist unnötig die Daten zweimal herumzukopieren, einmal reicht.</p>
<p>Und noch ein paar Tipps: Ersetze void append(String string) durch void append(const String &amp; string), es erspart dir ein unnötiges temporäres Objekt.<br />
Statt tmp[getSize()+i] = string.data[i]; speichere dir die Länge einmal in eine Variable.</p>
<pre><code class="language-cpp">int iSize = getSize();
...
tmp[iSize + i] = string.data[i];
</code></pre>
<p>Stell dir vor, du erweiterst nen 1 MB großes XML String mit nem weiteren 1 MB großen String. Da würdest du bei jedem einzelnen Zeichen per getSize() von 0 bis 1MB durchlaufen um zum '\0' zu gelangen. Das wären dann 1.000.000.000.000 Lese-Zugriffe (bzw. 1.099.511.627.776 <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="😃"
    /> ).<br />
Ein std::string speichert deshalb die Länge in einem weiteren Member, damit die nicht zur Laufzeit festgestellt werden muss.</p>
<p>Ich hab ja auch mal ne String-Klasse selbst geschrieben... da lernt man einiges daraus... dennoch wird man am Ende feststellen, dass man es kaum (oder nur unwesentlich) besser als std::string machen kann <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>lg XOR</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1871828</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1871828</guid><dc:creator><![CDATA[xor]]></dc:creator><pubDate>Sat, 20 Mar 2010 23:04:49 GMT</pubDate></item></channel></rss>