Ich krieg immer NAN und weiß nicht warum



  • Hallo,

    ich muss die komplexen Zahlen für ne Aufgabe modellieren und hab schonmal die Additionsfunktion geschrieben. Aber komischerweise krieg ich in der Ausgabe immer ein NAN:

    #include <iostream>
    
    using namespace std;
    
    struct Complex{
    	float real;
    	float imaginaer;
    
    	Complex *addition(Complex *b);
    	/*Complex *subtraktion(Complex *a, Complex *b);
    	Complex *multiplikation(Complex *a, Complex *b);
    	Complex *division(Complex *a, Complex *b);
    	float betrag(Complex *a);
    	Complex *konjugieren(Complex *a);*/
    };
    
    Complex *Complex::addition(Complex *b){
    	float tmp_real = real + b->real;
    	float tmp_imaginaer = imaginaer + b->imaginaer;
    	Complex p;
    	p.real = tmp_real;
    	p.imaginaer = tmp_imaginaer;
    	Complex *ptr = &p;
    	return ptr;
    }
    
    int main(){
    	Complex a, b;
    	a.real = 3.0f;
    	b.real = 9.0f;
    	a.imaginaer = 10.0f;
    	b.imaginaer = -2.0f;
    	Complex *res = a.addition(&b);
    	cout << res->real << ", " << res->imaginaer << endl;
    	return 0;
    }
    

    Wenn ich in der Funktion "addition" real und imaginaer ausgeben lasse, kommen 12 und 8 raus, aber wenn ich es in der main via dem Zeiger res ausgeben lasse, steht dann 12 und nan. Warum denn?



  • Du gibst eine ADresse auf eine lokale Variable zurück, das geht so nicht, die Variable stirbt bei Funktionsende.
    Du mußt hier auf die Zeiger verzichten und ganze Complex-Objekte zurückgeben.



  • p ist eine lokale Variable. Sie hört mit dem Verlassen der Funktion auf zu existieren. Wenn du einen Zeiger darauf zurückgibst und später dereferenzierst, greifst du also ins Leere, das Verhalten ist undefiniert.

    Hat es eigentlich einen tieferen Sinn, dass du mit Zeigern hantierst? Deine Ministruktur kannst du problemlos als Wert herumreichen.



  • Complex *ptr = &p;
    Damit erstellst du eine lokale Variable, die nach dem verlassen der Funktion gelöscht wird. Der Zeiger zeigt ins Nichts ("wilder Zeiger"). Wenn du unbedingt Zeiger benutzen willst dann schreibe statt

    Complex p;
    
    Complex* ptr = new Complex;
    

    Den Rückgabewert musst du dann aber in main() mit delete löschen um kein Speicherleck zu haben.



  • @volkard Aahhh, Danke. Oh Mann, wie konnte ich nur sowas vergessen ._.

    @Bashar Naja, ich hab mit Zeigern so meine Probleme, deshalb wollte ich explizit mit denen arbeiten, um mich darin zu üben. Ich komme aus der Java-Welt, wo ich mich um Zeiger usw. nicht kümmern musste^^. Aber jetzt wird's Zeit!

    @Oberon00 Danke für die Zeiger-Lösung 🙂



  • for(;;){//Endlosschleife, um im Taskmanager das Speicherloch zu sehen
       Complex* a=new Complex(1,2);
       Complex* b=new Complex(1,3);
       Complex* c=a->addiere(b)->addiere(c);
       delete a,b,c;//Wo ist der Speicher hin?
    }
    


  • lil_pingu schrieb:

    Naja, ich hab mit Zeigern so meine Probleme, deshalb wollte ich explizit mit denen arbeiten, um mich darin zu üben. Ich komme aus der Java-Welt, wo ich mich um Zeiger usw. nicht kümmern musste^^.

    Naja, so richtig doll kümmern muss man sich in C++ auch nicht -- d.h. wenn man mal das ganze new/delete Zeugs vermeidet. Das sollte die erste Regel für Konvertierende sein: "Probier's ohne new/delete" 😉



  • lil_pingu schrieb:

    @Bashar Naja, ich hab mit Zeigern so meine Probleme, deshalb wollte ich explizit mit denen arbeiten, um mich darin zu üben. Ich komme aus der Java-Welt, wo ich mich um Zeiger usw. nicht kümmern musste^^. Aber jetzt wird's Zeit!

    Eigentlich hantiert man in Java die ganze Zeit mit Zeigern, sie heißen nur anders.


Anmelden zum Antworten