Zeiger Initialiserung in Funktion



  • Hallo,
    ich möchte 2 Arrays in einer Funktion allokieren und mit Werten füllen, weiß aber nicht wie ich die uninitialisierte Zeiger übergeben soll.
    Anbei ein Beispiel mit einem Zeiger.
    Die Lösung mit der Rückgabe des Zeigers funktioniert leider nur mit einem Zeiger und ist damit für meinen Fall nicht anwendbar.

    void makePointer( double* pX ) { 
    	pX = new double; 
    	*pX = 1.; 
    	cout << "in function: pX =" << *pX << "adress of pX =" << pX;
    }
    double* makePointer( ) { 
    	double* pX = new double; 
    	*pX = 2.; 
    	cout << "in function2: pX =" << *pX << "adress of pX =" << pX;
    	return pX;
    }
    
    main( int argc, char** argv )
    {
    	double* myX = 0; double* myX2 = 0;
    	makePointer( myX );									// expecting getting the pointer myX actualized in function...
    //	cout << "after call: myX =" << *myX << "adress of myX =" << myX;		// ...but is not so! generates memory exception (Null pointer)	
    	myX2 = makePointer();								// works as expected
    	cout << "after call: myX2 =" << *myX2 << "adress of myX2 =" << myX2;
    }
    

    Ich hatte erwartet, daß der übergebene Zeiger myX im ersten Fall bei der Speicher Allokierung aktualisiert werden würde, dies ist jedoch nur innerhalb der Funktion der Fall, nach dem Rücksprung hat myX wieder den alten Wert 0.
    Hat jemand eine Idee wie ich mein Vorhaben realisieren kann?

    Danke.



  • void makePointer( double** pX ) { 
    	*pX = new double; 
    	**pX = 1.; 
    	cout << "in function: *pX =" << **pX << "adress of pX =" << pX;
    }
    
    main( int argc, char** argv )
    {
    	double* myX = 0; double* myX2 = 0;
    	makePointer( &myX
    


  • Das sieht mir sehr nach C aus. Da macht man so etwas meist mit Pointer auf Ponter. Warum nimmst du keinen vector?



  • Ich hatte erwartet, daß der übergebene Zeiger myX im ersten Fall bei der Speicher Allokierung aktualisiert werden würde, dies ist jedoch nur innerhalb der Funktion der Fall, nach dem Rücksprung hat myX wieder den alten Wert 0.

    Innerhalb der Funktion wird auch nicht myX verwendet, sondern der Funktionsparameter. Falls myX verändert werden sollte, hätte der Funktionsparameter eine Referenz sein sollen (oder sowie in Volkards Beispiel...).

    Ich verstehe allerdings nicht, warum du nicht einfach Variante zwei nimmst. Die ist sowieso sinnvoller im Bezug auf die Syntax beim Aufruf (in C++ erwartet man nicht immer, dass Funktionsargumente verändert werden).

    p = makePointer(); // intuitiv klar
    makePointer(p); // Muss erst Funktionssignatur nachschlagen
    

    Warum nimmst du keinen vector?

    Weil er hier nichts verloren hat? Ich sehe keine Arrays, du etwa?

    In diesem speziellen Beispiel sehe ich auch keine Gründe für dynamisch allokierte Skalare. Wofür brauchst du das genau? Und wenn du aus irgendeinem (hoffentich guten) Grund tatsächlich dynamisch allokieren musst, setze dich auf jeden Fall demnächst mit Smart-Pointern auseinander. Schon in deinem primitiven Beispiel oben ist Speicher nicht freigegeben worden. Das ist, mit anderen Worten, ein klassisches Speicherleck. Das verhindern ebenjene smarten Zeiger.



  • Der Zeiger muss per Referenz oder Pointer uebergeben werden und nicht per value. Desweiteren wird nirgends der angeforderte Speicher wieder freigegen.



  • Du machst call-by-value. Wenn du mit dem Original machen willst, musst du natürlich call-by-reference machen.

    Ich hoffe, du machst das nur zu Übungszwecken. In echt wirst du so etwas in C++ nie verwende. 😉



  • Sone schrieb:

    Warum nimmst du keinen vector?

    Weil er hier nichts verloren hat? Ich sehe keine Arrays, du etwa?

    Im Text schrieb er etwas von 2 Arrays die er allokieren möchte. Ich hatte den Code jetzt für ein vereinfachtes Beispiel gehalten. Wozu allokiert man denn ein einzelnes Double?



  • TNA schrieb:

    Im Text schrieb er etwas von 2 Arrays die er allokieren möchte. Ich hatte den Code jetzt für ein vereinfachtes Beispiel gehalten.

    Pardon, du hast Recht. Ich hatte das sogar gelesen und vergessen.

    Wozu allokiert man denn ein einzelnes Double?

    Stimmt. Das hat eigentlich praktisch keinen Zweck.

    Jetzt will ich aber kein Beispiel posten, weil ich dann Gefahr laufe, ausgeschimpft zu werden, dass er das noch nicht "hatte" und ihm das zu viel sei.



  • danke volkard. Jetzt ist es mir klar, daß ich einen Zeiger auf einen Zeiger nehmen muß (**argv läßt grüßen!).

    Ich schreibe einen C++ Wrapper für eine C-Bibliothek, also Mischtechnik.
    Ich hatte an einen Vektor gedacht, diese Funktion ist jedoch eine Utility-Funktion, die auch von C-Routinen aufgerufen werden kann.

    Dachte nicht daß ich so eine Lawine austreten würde... Danke an Alle für die Rege Duskussion.



  • alainstgt schrieb:

    danke volkard. Jetzt ist es mir klar, daß ich einen Zeiger auf einen Zeiger nehmen muß (**argv läßt grüßen!).

    Genau das wollte ich haben. 👍
    Wie Du den ** dann umgehen kannst, kommt danach, aber erstmal muss in der Basis Klarheit sein. Eine *& wäre wohl üblich. Läßt sich aber viel besser verstehen aus Sicht des **, finde ich.

    ~Bin ein wenig enttäuscht über die Welle.~


Anmelden zum Antworten