Struct Rückgabewert



  • One-Man-Army schrieb:

    Hi!

    http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29

    Ich habe es gerade bei mir versucht, das Programm läuft ohne Probleme. Allerdings wundert es mich ein bisschen.
    Guck mal nach ob dein Compiler evtl. ein Problem damit hat, dass du deine Struktur falsch definiert hast.

    typedef struct name { komponente_1, ..., komponente_n }
              variable_1, ..., variable_m;
    

    So sollte es normaler Weise aussehen.
    Seid Ihr euch sicher dass es Standardmäßig mit jedem Compiler funktioniert den Bezeichner ("name") hinter den Strukturrumpf zu schreiben? 😕

    Lg

    Danke, habs versucht... das ändert aber leider nichts.


  • Mod

    CJens schrieb:

    Ich glaube nicht. Ich muss das Skalarprodukt mehrerer Vektoren mit ein und dem selben Vektor vergleichen. Da spielt nicht nur die Länge, sondern auch der Winkel zwischen den Vektoren eine Rolle. Aber danke für den Hinweis, an der ein oder anderen Stelle konnte ich damit auf eine Wurzel verzichten.

    Winkel sind übrigens auch etwas, worauf man in einer Rechnung oft verzichten kann, wenn man nur gründlich nachdenkt, was man wirklich erreichen möchte. Ein Winkel ist eine typische Größe, die man einmal am Ende ausrechnet, wohingegen man beim eigentlichen Algorithmus oft mit dem cos(Winkel) auskommt (Also dem Skalarprodukt. Wobei hier eventuell eine Wurzel nötig ist, zwecks Normierung).

    Um ehrlich zu sein habe ich nichts gemessen.

    Dazu sag ich mal nur: 🙄

    Ich muss in meinem richtigen Programm, wofür ich diese Funktion schreibe, mehrere GB an Daten einlesen und dann verarbeiten. Alleine das Einlesen dauert etwa eine Minute und da merkt man es schon.

    Klingt so, als "misst" du höchstwahrscheinlich nur, dass du das eine Programm direkt ausführst, während beim anderen ein Debugger mitläuft.

    Übrigens kann ich eingrenzen, dass es definitiv an der Funktion GetVector liegt. Wenn ich nämlich diese auskommentiere, stürzt das Programm nicht ab.

    Gut, das ist doch schon einmal eine Spur. Hast du mal mein "Debug"programm aus meinem letzten Beitrag ausgeführt?

    Mit dieser Spur, kann ich das Debugprogramm auch noch einmal erweitern:

    #include <stdio.h>
    #include <math.h>
    
    typedef struct{
      double vx; //x value
      double vy; //y value
    } TVector;
    
    typedef struct{
      double x; //x value
      double y; //y value
    } TPoint;
    
    double Vektorlaenge(TVector* V)
    {
      double l2;
      double l;
      fprintf(stderr, "Vektorlaenge: V->vx: %f V->vy: %f\n", V->vx, V->vy);
      l2 = V->vx*V->vx + V->vy*V->vy;
      fprintf(stderr, "Vektorlaenge: l2: %f\n", l2);
      l = sqrt(l2);
      fprintf(stderr, "Vektorlaenge: l: %f\n", l);
      return l;
    }
    
    TVector GetVector(TPoint* P2, TPoint* P1){
      TVector V;
      fprintf(stderr, "GetVector: P1 %p P2: %p\n", (void*)P1, (void*)P2);
      V.vx = P2->x - P1->x;
      V.vy = P2->y - P1->y;
      fprintf(stderr, "GetVector: V.vx: %f V.vy: %f\n", V.vx, V.vy);
      return V;
    }
    
    int main(){
      TPoint P1, P2;
      TVector V;
      double l;
    
      P1.x = .0;
      P1.y = .0;
    
      P2.x=1.;
      P2.y=1.;
    
      fprintf(stderr, "main: &P1 %p &P2: %p\n", (void*)&P1, (void*)&P2);
    
      V = GetVector(&P2, &P1);
      fprintf(stderr, "main: V.vx: %f V.vy: %f\n", V.vx, V.vy);
    
      l = Vektorlaenge(&V);
      fputs("Laengenberechnung durchgefuehrt\n", stderr);
    
      printf("Vektorlaenge: %2.4f\n", l);
    
      getchar();
      return 0;
    }
    

    (Bitte per Copy&Paste einfügen. Nicht abtippen!)

    Erwartete Ausgabe sollte etwas in dieser Art sein (Konkrete Adressen können natürlich unterschiedlich sein, sie müssen nur in main und GetVector gleich sein):

    main: &P1 0x7fff69441180 &P2: 0x7fff69441170
    GetVector: P1 0x7fff69441180 P2: 0x7fff69441170
    GetVector: V.vx: 1.000000 V.vy: 1.000000
    main: V.vx: 1.000000 V.vy: 1.000000
    Vektorlaenge: V->vx: 1.000000 V->vy: 1.000000
    Vektorlaenge: l2: 2.000000
    Vektorlaenge: l: 1.414214
    Langenberechnung durchgefuehrt
    Vektorlaenge: 1.4142
    

    Beziehungsweise bei dir sollte es abstürzen, aber nicht ohne vorher wertvolle Hinweise preis zu geben.

    Bist du dir auch wirklich 100% sicher, dass das Programm hier im Forum 1:1 dem Programm bei dir entspricht? Die wahrscheinlichste Ursache ist meiner Meinung nach immer noch, dass du uns nicht das richtige Programm zeigst, sondern nur ein ähnliches. Vielleicht auch aus Versehen: Bist du sicher, dass du auch das aktuelle Programm übersetzt und ausführst und nicht eine alte, fehlerhafte Version? Du wärst nicht der Erste, dem das passiert.
    Ein einziges, anders gesetztes Zeichen würde schon alles erklären, da du hier mit rohen Pointern herum jonglierst. Deine Symptome sind auch die typischen Symptome, die man erhält, wenn man dabei etwas falsch macht. Bloß hier im Forum ist alles richtig im Code.

    CJens schrieb:

    One-Man-Army schrieb:

    ...

    Danke, habs versucht... das ändert aber leider nichts.

    Wie schon gesagt wurde, war die Antwort von One-Man-Army falsch. Es ist aber sehr komisch, dass dies nichts geändert haben sollte, denn das Programm wird dadurch falsch und kann nicht mehr funktionieren. Was wieder den Verdacht von oben herauf beschwört, dass du uns nicht den richtigen Code zeigst oder sonstwie falsche Angaben machst - ob absichtlich oder unabsichtlich. Du willst hier Hilfe. Wenn du uns etwas verheimlichst, können wir dir nicht helfen!

    Es liegt wohl an TCC

    Das ist so gut wie ausgeschlossen.



  • Das kam raus:

    main: &P1 00000000000012FEE0 &P2: 00000000000012FED0
    main: V.vx 0.000000 V.vy: 0.000000
    Vektorlaenge: V->vx 0.000000 V->vy: 0.000000
    Vektorlaenge l2: 0.000000
    Vektorlaenge l: 0.000000
    Laengenberechnung durchgefuehrt



  • SeppJ schrieb:

    Wie schon gesagt wurde, war die Antwort von One-Man-Army falsch. Es ist aber sehr komisch, dass dies nichts geändert haben sollte, denn das Programm wird dadurch falsch und kann nicht mehr funktionieren. Was wieder den Verdacht von oben herauf beschwört, dass du uns nicht den richtigen Code zeigst oder sonstwie falsche Angaben machst - ob absichtlich oder unabsichtlich. Du willst hier Hilfe. Wenn du uns etwas verheimlichst, können wir dir nicht helfen!

    typedef struct TVector{
      double vx; //x value
      double vy; //y value
    } TVector;
    
    typedef struct TPoint{
      double x; //x value
      double y; //y value
    } TPoint;
    

    Mein TCC Compiler gibt bei dieser Änderung keinen Fehler aus.
    Das Programm läuft aber weiterhin nicht - wie gesagt, ändert nichts.



  • Das funktioniert auch bei TCC:

    #include <stdio.h>
    #include <math.h>
    
    typedef struct TVector{
      double vx; //x value
      double vy; //y value
    } TVector;
    
    typedef struct TPoint{
      double x; //x value
      double y; //y value
    } TPoint;
    
    double Vektorlaenge(TVector* V)
    {
      double l2;
      double l;
      fprintf(stderr, "Vektorlaenge: V->vx: %f V->vy: %f\n", V->vx, V->vy);
      l2 = V->vx*V->vx + V->vy*V->vy;
      fprintf(stderr, "Vektorlaenge: l2: %f\n", l2);
      l = sqrt(l2);
      fprintf(stderr, "Vektorlaenge: l: %f\n", l);
      return l;
    }
    
    int GetVector(TVector* V, TPoint* P2, TPoint* P1){ //Änderung
      V->vx = P2->x - P1->x; //Änderung
      V->vy = P2->y - P1->y; //Änderung
      return 0; //Änderung
    } //Änderung
    
    int main(){
      TPoint P1, P2;
      TVector V;
      double l;
    
      P1.x = .0;
      P1.y = .0;
    
      P2.x=1.;
      P2.y=1.;
    
      fprintf(stderr, "main: &P1 %p &P2: %p\n", (void*)&P1, (void*)&P2);
    
      GetVector(&V, &P2, &P1); //Änderung
      fprintf(stderr, "main: V.vx: %f V.vy: %f\n", V.vx, V.vy);
    
      l = Vektorlaenge(&V);
      fputs("Laengenberechnung durchgefuehrt\n", stderr);
    
      printf("Vektorlaenge: %2.4f\n", l);
    
      getchar();
      return 0;
    }
    

  • Mod

    CJens schrieb:

    main: &P1 00000000000012FEE0 &P2: 00000000000012FED0
    main: V.vx 0.000000 V.vy: 0.000000
    Vektorlaenge: V->vx 0.000000 V->vy: 0.000000
    Vektorlaenge l2: 0.000000
    Vektorlaenge l: 0.000000
    Laengenberechnung durchgefuehrt

    😮 Gremlins? Der Klabautermann? Das ist ja unheimlich.
    Ändere mal beide Vorkommen von "GetVector" in "FooBar123" und guck, was passiert. Übersetz das ursprüngliche Programm auch einmal mit der Kommandozeilenoption "-Wall" (mit Minus, aber ohne Anführungszeichen) für den tcc.

    CJens schrieb:

    typedef struct TVector{
      double vx; //x value
      double vy; //y value
    } TVector;
     
    typedef struct TPoint{
      double x; //x value
      double y; //y value
    } TPoint;
    

    Mein TCC Compiler gibt bei dieser Änderung keinen Fehler aus.
    Das Programm läuft aber weiterhin nicht - wie gesagt, ändert nichts.

    Ach so, dann hast du was anderes gemacht, als ich dachte. So ist ok.


  • Mod

    CJens schrieb:

    Das funktioniert auch bei TCC:

    Irgendwie ahne ich es. Probier mal, ob folgendes Programm läuft:

    #include <stdio.h>
    #include <math.h>
    
    struct Foo
    {
      int i, j, k, l;
    };
    
    int main()
    {
      struct Foo foo = {0};
      struct Foo bar = {0};
      GetVector(&foo, &bar);
      puts("Erfolg!");
      getchar();
      return 0;
    }
    

    Ja, das ist richtig, hier ist keine Definition von GetVector im Programm.

    edit: Korrigiert für alle Eventualitäten.

    P.S.: Wenn obiges läuft, dann liegt es letztlich doch am TCC, aber auf eine Art und Weise, die ich ohne die Debugausgabe nie vermutet hätte. Man kann es wahrscheinlich noch retten, wenn du auf dem TCC bestehst (anderen Linker benutzen), aber wie auch schon gesagt wurde, ist der TCC sowieso nicht unbedingt eine gute Wahl, wenn du auf Performance des Endresultats bestehst.



  • Der Fehler bleibt bestehen.

    #include <stdio.h>
    #include <math.h>
    
    struct TVectoroo{
      double vx; //x value
      double vy; //y value
    };
    
    struct TPointoo{
      double x; //x value
      double y; //y value
    };
    
    double Vektorlaenge(struct TVectoroo* V)
    {
      double l2;
      double l;
      fprintf(stderr, "Vektorlaenge: V->vx: %f V->vy: %f\n", V->vx, V->vy);
      l2 = V->vx*V->vx + V->vy*V->vy;
      fprintf(stderr, "Vektorlaenge: l2: %f\n", l2);
      l = sqrt(l2);
      fprintf(stderr, "Vektorlaenge: l: %f\n", l);
      return l;
    }
    
    struct TVectoroo GetVector(struct TPointoo* Poo2, struct TPointoo* Poo1){
      struct TVectoroo fV = {Poo2->x - Poo1->x, Poo2->y - Poo1->y};
      return fV;
    }
    
    int GetVectorOld(struct TVectoroo* Voo, struct TPointoo* Poo2, struct TPointoo* Poo1){
      Voo->vx = Poo2->x - Poo1->x;
      Voo->vy = Poo2->y - Poo1->y;
      return 0;
    } 
    int main(){
      struct TPointoo Poo1;
      struct TPointoo Poo2;
      struct TVectoroo Voo;
      double loo;
    
      Poo1.x = .0;
      Poo1.y = .0;
    
      Poo2.x=1.;
      Poo2.y=1.;
    
      fprintf(stderr, "main: &P1 %p &P2: %p\n", (void*)&Poo1, (void*)&Poo2);
    
      Voo = GetVector(&Poo2, &Poo1);
      fprintf(stderr, "main: V.vx: %f V.vy: %f\n", Voo.vx, Voo.vy);
    
      loo = Vektorlaenge(&Voo);
      fputs("Laengenberechnung durchgefuehrt\n", stderr);
    
      printf("Vektorlaenge: %2.4f\n", loo);
    
      getchar();
      return 0;
    }
    

    Auch das Argument Wall hat nicht geholfen... der Compiler hat in beiden Fällen keinen Fehler angezeigt.


  • Mod

    Du hast ja auch nicht gemacht, was ich gesagt habe. Du sollst "GetVector" durch einen anderen Bezeichner ersetzen. Du hast hingegen alle anderen Bezeichner ersetzt und GetVector unberührt gelassen.

    #include <stdio.h>
    #include <math.h>
    
    typedef struct{
      double vx; 
      double vy; 
    } TVector;
    
    typedef struct{
      double x; 
      double y; 
    } TPoint;
    
    double Vektorlaenge(TVector* V)
    {
      double l2;
      double l;
      fprintf(stderr, "Vektorlaenge: V->vx: %f V->vy: %f\n", V->vx, V->vy);
      l2 = V->vx*V->vx + V->vy*V->vy;
      fprintf(stderr, "Vektorlaenge: l2: %f\n", l2);
      l = sqrt(l2);
      fprintf(stderr, "Vektorlaenge: l: %f\n", l);
      return l;
    }
    
    TVector GetVectoroo(TPoint* P2, TPoint* P1){  // Änderung
      TVector V;
      fprintf(stderr, "GetVector: P1 %p P2: %p\n", (void*)P1, (void*)P2);
      V.vx = P2->x - P1->x;
      V.vy = P2->y - P1->y;
      fprintf(stderr, "GetVector: V.vx: %f V.vy: %f\n", V.vx, V.vy);
      return V;
    }
    
    int main(){
      TPoint P1, P2;
      TVector V;
      double l;
    
      P1.x = .0;
      P1.y = .0;
    
      P2.x=1.;
      P2.y=1.;
    
      fprintf(stderr, "main: &P1 %p &P2: %p\n", (void*)&P1, (void*)&P2);
    
      V = GetVectoroo(&P2, &P1);  // Änderung
      fprintf(stderr, "main: V.vx: %f V.vy: %f\n", V.vx, V.vy);
    
      l = Vektorlaenge(&V);
      fputs("Laengenberechnung durchgefuehrt\n", stderr);
    
      printf("Vektorlaenge: %2.4f\n", l);
    
      getchar();
      return 0;
    }
    


  • Hallo

    Hab den Code wie von Dir geschrieben übernommen, fehlerfrei kompiliert... beim Ausführen kommt es jedoch zum bekannten falschen Ergebnis und Absturz.



  • Hab exakt das gleiche *.c File auf mein Netbook kopiert und dort mit dem TCC Compiler kompiliert. Läuft einwandfrei.
    Auf dem Netbook hab ich jedoch den 32Bit Kompiler installiert.


  • Mod

    CJens schrieb:

    Hab den Code wie von Dir geschrieben übernommen, fehlerfrei kompiliert... beim Ausführen kommt es jedoch zum bekannten falschen Ergebnis und Absturz.

    Da bin ich jetzt schwer überrascht. Ich hätte nach den bisherigen Tests schwören können, dass da was falsch gelinkt wird und es an dem Bezeichner "GetVector" liegt. Aber wenn "GetVectoroo" auch nicht funktioniert, bin ich ratlos. Hat sich die Ausgabe denn auch nicht verändert? Beim vorherigen Versuch wurde die Funktion schließlich überhaupt nie aufgerufen.

    CJens schrieb:

    Hab exakt das gleiche *.c File auf mein Netbook kopiert und dort mit dem TCC Compiler kompiliert. Läuft einwandfrei.
    Auf dem Netbook hab ich jedoch den 32Bit Kompiler installiert.

    Das wiederum ist nicht so überraschend. Wie schon oft gesagt wurde, das Programm ist eigentlich korrekt (und dazu auch nicht sehr komplex). Das muss eigentlich auf jedem System mit jedem Compiler übersetzbar und ausführbar sein. Bei deinem Hauptsystem muss irgendein ganz verworrener Fehler vorliegen.


Anmelden zum Antworten