kostenloser Webspace werbefrei: lima-city


Simple Frage zu Referenz in C++ und Qt

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    sebastian-online

    sebastian-online hat kostenlosen Webspace.

    Hallo zusammen,

    ich brauche mal eure Hilfe:

    Was ist der Unterschied zwischen:
    QString szItem = "Test";
    QString& szItemAnd = szItem;
    szItem = QString(szItemAnd);

    und
    QString szItem = "Test";
    ?

    In szItem sollte doch das Selbe stehen, oder?
    Beides wird einem Datenbankprogramm gegeben:
    -Beim ersten stürzt das Programm ab.
    -Beim zweiten läuft es so wie gewünscht.


    Grüße
    Sebastian

    PS:
    Bitte keine Antwort:
    -Poste doch mal den kompletten Code. -> Das macht keinen Sinn, weil ich genau dies als Ursache herausgearbeitet habe.
    - Bitte nur antworten, wenn man wirklich eine Idee hat (Compiler VS2008).





    Beitrag zuletzt geändert: 4.8.2014 15:23:55 von sebastian-online
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hi,

    ich war mit dieser problematik bisher noch nie konfrontiert, aber ich kann mir folgendes denken:

    QString braucht laut Dokumentation(http://qt-project.org/doc/qt-4.8/qstring.html) Unicode, standard-Abspeicher-Zeichensatz ist UTF-8 im VS. Da ich zu dieser problematik jetzt auch keine Ahnung habe, aber weiß, wie du da schnell dran rankommst, empfehle ich dir folgendes:

    hau auf die Zeile

    QString szItem = "Test";


    einen breakpoint. Sobald er da reinstepped, gehst du mit F11 die einzelbnen schritte durch, bis der Fehler fliegt.


    Es könnte auch sein, dass der & Parameter überladen wurde und deswegen was anderes rauskommt, als was du erwarten würdest. Schau dir dazu oben gepostete Doku an...

    das wär so der erste Verdacht, den ich habe als jemand, der zwar C kann, aber QT noch nie was mit gemacht hat...
  4. Autor dieses Themas

    sebastian-online

    sebastian-online hat kostenlosen Webspace.

    Danke für deine Mühe.

    Also:
    - Der &-operator ist nicht überschrieben.
    Debuggen geht nicht, da das Ganze über das Netzwerk ausgeführt wird mit unterschiedlichen Stationen (Terminals). Es ließen sich auch nur mit Mühe einzelne Funktionen isolieren.

    Ich vermute mal, dass es irgend ein Compilerfehler ist. Ich habe jetzt alles mit Zeigern laufen.

    Viele Grüße
    Sebastian
  5. Hallo sebastian-online,

    dein Problem im ersten Beispiel kommt folgendermaßen zustande:
    Die Zeile
    QString szItem = "Test";
    erzeugt ein QString-Objekt auf dem Stack, welche beim eintreten in die Funktion initialisiert wird. Damit auch alles wieder ordentlich aufgeräumt wird baut der Compiler am Ende der Funktion eine Destruktoraufruf ein.
    Hierbei ist zu beachten, dass QString für den Text Speicher auf dem Heap reserviert, welcher im Destruktor freigegeben wird.

    Der Bug ist dann die folgende Zeile:
    szItem = QString(szItemAnd);
    Hierbei wird ein neues/zweites QString-Objekt erzeugt und dieses als flache Kopie über szItem kopiert. Dabei wird insbesondere die Speicheradresse des Textes im Heap überschrieben. D.h. das erste und das zweite QString-Objekt verweisen jetzt auf den Text-Speicherbereich des zweiten QString-Objektes. Die Adresse des ersten Objektes ist verloren und man hat daher ein Memory-Leak.
    Der Compiler merkt aber, dass das zweite QString-Objekt nach dieser Zeile nicht weiter benötigt wird, weshalb er gleich nach dieser Zeile einen Destruktor-Aufruf für das zweite QString-Objekt einfügt.
    Jetzt verweist die Heap-Adresse des ersten QString-Objektes auf einen bereits freigegebenen Speicherbereich.
    Sofern ein Zugriff auf diesen Speicher nicht bereits zum Programmabsturz führt kommt es spätestens beim Verlassen der Funktion, wenn der Destruktor aufgerufen wird, dazu, weil dieser versucht den bereits freigegenenen Speicherbereich erneut freizugeben.

    Hier noch zwei Beispiele zur Illustration mit dem Debugger:
    1. Kein Problem:
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
      public:
      Test(int i):value(i) {}
      Test(const Test& t):value(t.value) {}
      ~Test(){}
      int get() { return value; }
      void set(int i) { value = i; }
    	
      private:
      int value;
    };
    
    int main(int argc, char ** argv)
    {
      Test t = 3;	
      cout << t.get() << endl;	
      t = Test(4);
      cout << t.get() << endl;
      return 0;
    }

    2. Crash:
    #include <iostream>
    
    using namespace std;
    
    class Test
    {
      public:
      Test(int i) { value = new int[1]; value[0] = i;}
      Test(const Test& t) {value = new int[1]; value[0] = t.value[0];}
      ~Test(){ delete[] value; }
      int get() { return value[0]; }
      void set(int i) { value[0] = i; }
    	
      private:
      int * value;
    };
    
    int main(int argc, char ** argv)
    {
      Test t = 3;
      cout << t.get() << endl;
      t = Test(4);
      cout << t.get() << endl;
      return 0;
    }




  6. Autor dieses Themas

    sebastian-online

    sebastian-online hat kostenlosen Webspace.

    Klasse Antwort! Vielen Dank.

    Ich löse jetzt alles über Pointer. Mit den Referenzen gab es auch dann einen Absturz, obwohl ich nicht wieder die selbe Variable (szItem) überschrieben habe. Aber naja.

    Vielen Dank
    Sebastian
  7. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!