Pointer-Problem: Anfänger



  • Hm, was meinst du mit "funktioniert nicht"?

    Ob du den pointer auf die Matrix nun per Wert (Version a) oder per Referen/pointer surchreichst, sollte eigentlich keinen nennenswerten Unterschied machen, eventuell wirds sogar so weit wegoptimiert, dass das selbe bei rauskommt...



  • Bei beispiel 1 gibt es einen segmentation fault....bei beispiel 2 nicht.

    Ich lege den pointer so an: Matrix* M = NULL;



  • also ich glaube das Problem liegt darin:

    [cpp]
    Matrix *M;

    ...

    my_function(M);

    Class::my_function(Matrix *M)
    {
    M = my_function2(M);
    M->set_length(4);
    }

    Matrix* Class::my_function2(Matrix *M)
    {
    M = New_Matrix();
    return M;
    }
    [/cpp]

    kann es sein dass durch die Methode New-Matrix() da irgendwas nicht passt - dort gebe ich einen Pointer zurück auf einen Heap-Bereich....



  • Ok also nochmals anders:

    Es ist ein triviales Problem bei dem ich nicht mehr durchblicke.

    Matrix * a = NULL;
    
    //pointer a wird initialisiert und zeigt auf etwas
    
    my_function(a);
    //auf len zugreifen löst segfault aus
    std::cout << a->lines->len << std::endl;
    
    //....
    void Class::my_function(Matrix *a)
    {
        my_function2(a);
    }
    
    //...
    void Class::my_function2(Matrix *a)
    {
          //Hier mache ich was mim pointer also greife
        //z.B auf Daten zu und verändere:
        a->lines->len = 4;
    }
    

    also irgendwas ist da falsch weil ich kann in der ausgangsfunktion als da wo my_function() aufgerufen wird nicht ohne einen seg-fault auf len zugreifen.

    Wenn ich statt dieser variante folgendes mache gehts - ist das so üblich wie ich es mache folgt?:

    Matrix * a = NULL;
    
    //pointer a wird initialisiert und zeigt auf etwas
    
    my_function(a);
    //auf len zugreifen geht
    std::cout << a->lines->len << std::endl;
    
    //....
    void Class::my_function(Matrix *&a)
    {
        my_function2(a);
    }
    
    //...
    void Class::my_function2(Matrix *&a)
    {
          //Hier mache ich was mim pointer also greife
        //z.B auf Daten zu und verändere:
        a->lines->len = 4;
    }
    

    oder ist das hier besser?

    Matrix * a = NULL;
    
    //pointer a wird initialisiert und zeigt auf etwas
    
    my_function(&a);
    //auf len zugreifen geht
    std::cout << a->lines->len << std::endl;
    
    //....
    void Class::my_function(Matrix **a)
    {
        my_function2(&a);
    }
    
    //...
    void Class::my_function2(Matrix **a)
    {
          //Hier mache ich was mim pointer also greife
        //z.B auf Daten zu und verändere:
        (*a)->lines->len = 4;
    }
    

    danke für eure Hilfe



  • Erstens: Ich hoffe doch, vor dem Zugriff (in der my_function2()) hast du etwas Speicher hinter dem Pointer angelegt, sonst gäbe es dort auch einen SegFault.

    Zweitens: Bei Variante 1 übergibst du eine Kopie des Zeigers, d.h. das globale 'a' bekommt gar nicht mit, wenn du in deinen Funktionen etwas zuweist. Bei Variante 2 und 3 (2 ist C++'iger ;)) übergibst du eine Referenz bzw. Zeiger auf dein globales 'a' und alle Aktionen wirken direkt durch.



  • Ich bin zwar selbst erst Anfänger in Sachen C++ aber ich werde das Gefühl nicht los, dass Du (Original-Poster) der Annahme unterliegst, ein Pointer (Zeiger) ist gleich dem Objekt, auf den er zeigen soll.

    int a = 12; <-- a ist eben ein int-Objekt mit dem Wert 12

    int *b = 12; <-- wäre ein Zeiger auf ein int-Objekt, welches (im Speicher) bei der Adresse 12 liegt.

    Die Dereferenzierung von Zeiger b: *b gibt dir also nicht 12, sondern den Wert der bei Adresse 12 liegt -> also was vollkommen undefiniertes.

    int *b = &a; <-- & ermittelt die Adresse (im Speicher) von a und diese wird dann b zugewiesen. Zu zeigt b nun auf a (im Speicher). Die Dereferenzierung *b gibt nun das gewünschte Ergebnis: 12.
    und haben für sich alleine soviel Aussagekraft wie
    Was für int-Objekte gilt, gilt für alle anderen auch.

    Pointer/Zeiger sind eigenständige Objekte/Variablen.

    Ich hoffe ich konnte ein bisschen aufklären. Korrigiert mich bitte, wenn ich falsch liege. 😉

    Regards...

    Heiko



  • int *b = 12; <-- wäre ein Zeiger auf ein int-Objekt, welches (im Speicher) bei der Adresse 12 liegt.

    du kannst doch keinen int einem int* zuweisen.....



  • int* 's sind intergale Werte, die dann implizit koncvertiert werden, wenn du sie einem int zuweist oder umgekehrt. geratenerweise wuerde die Ardesse (der Wert des pointers) nach obigem Ausdruck etwa so aussehen:

    0x0C000000 oder 0x0000000C (0x0C = hexadezimal 12)



  • pumuckl schrieb:

    int* 's sind intergale Werte, die dann implizit koncvertiert werden, wenn du sie einem int zuweist oder umgekehrt.

    In C++ werden Typen unterschiedlicher Indirektionsebenen nicht implizit konvertiert. In C++ werden nichtmal unterschiedliche Typen gleicher Indirektionsebene konvertiert (ausser die Konvertierung ist trivial, Bsp. short nach int). Nichtmal void* wird implizit in einen anderen Zeigertyp umgewandelt. Zum Glück.



  • Du hast vollkommen recht. Es funktioniert lediglich

    int a* = 0; // NULL ist z.B. in iostream mit 0 definiert

    Ersetze 12 im Bezug auf den Pointer durch 0 😉

    Das ändert jetzt aber auch nichts an der Kernaussage. Ein einsamer Pointer (z.B. Matrix * a = NULL) hat soviel Sinn wie ein Kubikmeter Luft bei 20°C. Wie die Poster vor mir schon bemerkten, kannst du den Pointer erst verwenden, wenn du ein konkretes Objekt hast, dessen Adresse du (bzw. der Pointer) kennst:

    Matrix mymatrix;
    Matrix* myptr_to_mymatrix = &mymatrix;

    oder

    Matrix* myptr_to_a_matrix = new Matrix; // <-- hier aber nicht das delete.. vergessen.

    nicht sinnvoll ist

    Matrix* myptr_to_a_matrix = NULL;

    wenn du kein konkretes Matrix-Objekt anlegst. Beim Aufruf von *myptr_to_a_matrix würde dein Programm versuchen auf ein Matrix-Objekt zuzugreifen, welches sich ab Adresse 0 im Speicher befindet (und da ist mit Sicherheit keins!).

    Grüße aus dem Sauerland...

    Heiko

    EDIT:

    Dein Anfangsproblem habe ich ganz aus den Augen verloren. Ich habe kurzerhand ein Beispielprogramm erstellt, welches (hoffentlich) annähernd deinem Problemfall entspricht.

    [cpp]#include <iostream>
    
    void fill_array(float* array, int array_length);
    void display_array(float* array, int array_length);
    
    int main(int argc, char** args)
    	{
    		const int arr_length = 20;
    		float array[arr_length];
    
    		fill_array(array, arr_length);
    		display_array(array, arr_length);
    
    		return 0;
    	}
    
    void fill_array(float* array, int array_length)
    	{
    		// Array mit 13.5 + i auffüllen
    		for(int i = 0; i < array_length; i++) {
    			array[i] = 13.5 + static_cast<float>(i);
    		}
    	}
    
    void display_array(float* array, int array_length)
    	{
    		// Array ausgeben
    		for(int i = 0; i < array_length; i++) {
    			std::cout << array[i] << " ";
    		}
    		std::cout << std::endl;
    	}	
    [/cpp]
    

    Kritik erwünscht.

    Grüße...

    Heiko



  • hm. wieder was gelernt.


Anmelden zum Antworten