Rekursiver Zugriff auf Verschachtelte Klassen geht schief -> segmentation fault



  • Danke dir. Wie meinst zusammensetzen? Ein Beispiel wäre nett.

    "Warum muss das denn unbedingt so gemacht werden wie du es versuchst?"
    Weil ich die Methoden so geliefert bekomme.
    soap_call___ns1__test(...)
    Der WebService wurde von einem Systemhaus so erstellt.


  • Mod

    Manuel_XY schrieb:

    Kannst das bitte genauer beschreiben?
    Die Initialisierung steht doch darüber.

    Deine Frage bestätigt, was ich befürchtet habe. Wenn du glaubst, dass

    _ns1__test*        a        = new _ns1__test;
    ns1__ArrayOfTests    incomingTests    = new ns1__ArrayOfTests;
    ns1__Tests*        Tests        = new ns1__Tests;
    ns1__TestIn        testin        = new ns1__TestIn;
    

    irgendetwas im Objekt a initialisiert, dann solltest du erstmal nochmal die Grundlagen von C++ lernen, besonders die Grundlagen über Klassen, Member, Scopes, Konstruktoren und ähnliches.



  • Ja bin noch Anfänger und komme aus der C-Welt.

    "incomingTests selber ist initialisiert, aber a->incomingTests nicht."
    Wie geht das? Muss ich dazu die Klassen manipulieren (weil die wurden von gsoap automatisch gerniert)?

    Eine kurze Beispiel-Lösung wäre freundlich 🙂


  • Mod

    Manuel_XY schrieb:

    Ja bin noch Anfänger und komme aus der C-Welt.

    "incomingTests selber ist initialisiert, aber a->incomingTests nicht."
    Wie geht das? Muss ich dazu die Klassen manipulieren (weil die wurden von gsoap automatisch gerniert)?

    Das wäre eine Möglichkeit.

    Eine kurze Beispiel-Lösung wäre freundlich 🙂

    Ungern, denn dann lerst du ja nicht, wo der Fehler liegt. An sich, würde ich die Klassen auch ganz anders designen, damit sowas gar nicht nötig ist.

    Aber um dir mal zu erklären, was du gemacht hast, will ich mal ein etwas übersichtlicheres Beispiel bemühen:

    struct bar
    {
     int daten;  // Die eigentlichen Daten
    }
    
    struct foo   // Ein struct, dass einen Zeiger auf bar enthält
    {
     bar * mbar;
    }
    
    int main(){
     foo * a;             // Ein Zeiger auf foo, aber noch uninitialisiert, das heißt, a->mbar gibt es noch nicht.
     a = new foo;         // Jetzt zeigt a auf ein Objekt vom Typ foo. a->mbar existiert, ist aber noch uninitialisiert
     a->mbar = new bar;   // a->mbar zeigt jetzt auf ein Objekt vom Typ bar, welches ein int Element namens Daten enthält, welches nicht initialisiert ist
     a->mbar.daten=1;     // Jetzt hat daten im bar Objekt auf das der Zeiger mbar im foo Objekt a zeigt den Wert 1
    }
    

    Und das war jetzt ein minimal abgespecktes Beispiel von dem was du da machst. Wie du siehst, ist das ein bisschen umständlich. Und hinterher muss das ganze auch wieder freigegeben werden, was nochmal so kompliziert und fehleranfällig ist. Ist halt suboptimales Design.

    Wieso eigentlich alle Elemente auf dem heap? Spricht was dagegen, das auf dem stack zu machen?



  • Helzlichen Dank für deine Mühe!
    Ich werde es gleich morgen früh in dieser Art ausprobieren.

    Ja die Strukturen sind umständlich aufgebaut.
    Aber wie gesagt, der WebService wurde extern entwickelt.
    Und um den Service in einer C++ Applikation verwenden zu können, habe
    ich gsoap eingesetzt. Es generiert aus der WebService-Beschreibungsdatei
    C++ Code. So kam dieser Aufbau zustande.



  • Ok verstanden. Wie kann ich nun das Problem beheben, also spricht uninitialiesiert von x->y wegbekommen.

    Ich kann den von gsoap-erstellte Quellcode schlecht ändern, da
    sonst der Webservice nicht mehr funktioniert.

    Gibt es eine Möglichkeit das Problem zuheben an der Stelle
    wo die Zuweisung passiert?

    a->incomingTests->Tests[0]->testin->id = "asdf";
    

  • Mod

    Manuel_XY schrieb:

    Ok verstanden. Wie kann ich nun das Problem beheben, also spricht uninitialiesiert von x->y wegbekommen.

    😕 Wenn du das was ich geschrieben habe, verstanden hast, dann hast du auch das Problem gelöst. 😕

    Kann es sein, dass du einfach nur erwartest, dass dir jemand dein Programm schreibt? Falls ja: Hier gibt's dafür auch ein Projekteforum.



  • nein ich hab leider nur keinen Plan wie ich x->y initialisieren kann.
    Nach meinem Verständnis sollte es die jeweiligen Instanzen nach new geben.



  • erbarme dich doch einfach 🙂
    und geb mir bitte einen Tipp.



  • Das hat dir doch schon SeppJ geschrieben, also in der Form:

    a->incomingTests = new ...;
    a->incomingTests->Tests = new ...;
    a->incomingTests->Tests[0] = new ...;
    a->incomingTests->Tests[0]->testin = new ...;
    
    a->incomingTests->Tests[0]->testin->id = "asdf";
    

    Jedoch scheint das ein eigenartiger WebService zu sein, wenn man so ein Gefrickel betreiben muß...



  • _ns1__test* a = new _ns1__test;
    a->incomingTests = new ns1__ArrayOfTests;
    a->incomingTests->Tests[0] = new ns1__Tests;
    a->incomingTests->Tests[0]->testin = new ns1__TestIn;
    a->incomingTests->Tests[0]->testin->uniqueid = "asdf";
    

    genau das habe ich heute morgen ausprobiert.
    Leider bekomme ich so auch einen segfault! 😞



  • _ns1__test* a = new _ns1__test;
    a->incomingTests = new ns1__ArrayOfTests;
    a->incomingTests->Tests = new ns1__Tests;      //neu
    a->incomingTests->Tests[0] = new ns1__Tests;
    a->incomingTests->Tests[0]->testin = new ns1__TestIn;
    a->incomingTests->Tests[0]->testin->uniqueid = "asdf";
    

    hilft leider auch nicht



  • Eine wichtige Zeile fehlt bei dir aber... (wobei ich zugeben muß, daß ich auch ein Detail vergessen hatte):

    a->incomingTests->Tests = new ns1__Tests*[1]; // Arraygröße angeben!!!
    

    Edit:
    wobei

    ns1__Tests*                          *Tests
    

    ganz fies formatiert ist (da es sich hierbei um einen Doppelzeiger (**) handelt)!



  • Scheint zu funktionieren!

    P.S. Ich liebe dich 😛



  • Hab noch eine Frage.
    Kann ich Objekte explizit auf NULL setzten?

    ...
    a->incomingTests->Tests[0]->testin = new ns1__TestIn;
    a->incomingTests->Tests[0]->testin = NULL;
    

    Oder sind die automatisch NULL nach dem sie instanziiert wurden,
    also nach

    a->incomingTests->Tests[0]->testin = new ns1__TestIn;
    


  • Manuel_XY schrieb:

    Kann ich Objekte explizit auf NULL setzten?

    Ja.

    a->incomingTests->Tests[0]->testin = new ns1__TestIn;
    a->incomingTests->Tests[0]->testin = NULL;
    

    Ähm... syntaktisch ist das in Ordnung. Ob es auch sinnvoll ist... schwer zu sagen. Wahrscheinlich nicht. Willst du denn nichts weiter mit dem Objekt machen? Zum Beispiel wieder löschen?

    Die Bezeicher mit den doppelten Underscores, die das Frickelwerk von gsoap da ausspuckt, sind nicht nur grauenvoll zu lesen, die sind noch nicht einmal erlaubt in C++. Da kannst du nix dafür, aber den gsoap-Programmierer sollte man dafür steinigen.



  • Herzlichen Dank für die schnelle Antwort.
    Ein paar Objekte müssen NULL für die Verarbeitung auf Server-Seite sein, deshalb. 🙂



  • Registrierter Troll schrieb:

    Die Bezeicher mit den doppelten Underscores, die das Frickelwerk von gsoap da ausspuckt, sind nicht nur grauenvoll zu lesen, die sind noch nicht einmal erlaubt in C++. Da kannst du nix dafür, aber den gsoap-Programmierer sollte man dafür steinigen

    Lt. aktuellem Standard ists legal(nur die führenden unterstriche spielen eine rolle) - allerdings steht im working draft von 2005, dass zukünftig alle bezeichner, die nen doppelten Unterstrich enthalten, für die implementierung reserviert sind...

    bb



  • unskilled schrieb:

    Lt. aktuellem Standard ists legal(nur die führenden unterstriche spielen eine rolle) - allerdings steht im working draft von 2005, dass zukünftig alle bezeichner, die nen doppelten Unterstrich enthalten, für die implementierung reserviert sind...

    Welchen Standard meinst du?

    ISO/IEC 14882, Second edition (2003-10-15) - 17.4.3.1.2 Global names schrieb:

    Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.



  • Registrierter Troll schrieb:

    unskilled schrieb:

    Lt. aktuellem Standard ists legal(nur die führenden unterstriche spielen eine rolle) - allerdings steht im working draft von 2005, dass zukünftig alle bezeichner, die nen doppelten Unterstrich enthalten, für die implementierung reserviert sind...

    Welchen Standard meinst du?

    ISO/IEC 14882, Second edition (2003-10-15) - 17.4.3.1.2 Global names schrieb:

    Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.

    hmm... verdammt, mein "aktueller" standard ist wohl doch etwas veraltet 😉
    gibts den 2003er iwo (kostenlos) zum dl? ^^

    bb


Anmelden zum Antworten