Pointer auf Liste



  • Hallo zusammen. ich spiele mich seit stunden mit einem (scheinbar) kleinen problem und komm aber leider einfach auf kein vernünftiges ergebnis. vielleicht könnt ihr mir ja helfen!?

    folgendes problem: ich ruf eine funktion auf und möcht dort ein array mit lauter zahlen erstellen. danach möcht ich einen pointer (der auf der erste element des arrays zeigt) an das hauptprogramm zurückschicken. im hauptprogramm möchte ich dann das array ausgeben (d.h.: den inhalt das pointers und danach die adresse um 1 erhöhen um quasis das 2te element des array zu erhalten.) ABER: es klappt einfach nicht!? 😞
    das problem ist glaub ich, dass der speicher im hauptprogramm nicht mehr der selbe, wie in der funktion ist. aber vielleicht liegt der fehler ja ganz wo anders.... hoffe also auf eure unterstützung. folgenden code habe ich entwickelt. vielleicht hilft er ja zur lösung des problems (die ganzen cout dienen nur zu testzwecken):

    int* eingabe()
    {
    int *ptr = NULL;
    int arr[3] = {1,2,3};
    ptr = &arr[0];

    cout << "ptr - arr[0]: " << ptr << " *ptr - arr[0]: " << *ptr << endl;
    cout << "ptr - arr[1]: " << (ptr+1) << " *ptr - arr[1]: " << *(ptr+1) << endl;
    cout << "ptr - arr[2]: " << (ptr+2) << " *ptr - arr[2]: " << *(ptr+2) << endl;
    cout << "&arr[0]: " << &arr[0] << " arr[0]: " << arr[0] << endl;
    cout << "&arr[1]: " << &arr[1] << " arr[1]: " << arr[1] << endl;
    cout << "&arr[2]: " << &arr[2] << " arr[2]: " << arr[2]<< endl;
    return ptr;
    }

    void main()
    {
    int *p;
    p = eingabe();

    cout << *(p) << endl <<endl;
    cout << (p+1) << " " << *(p+1) << endl << endl;
    cout << (p+2) << " " << *(p+2) << endl << endl;

    }

    DANKE für eure hilfe.

    lg Taube



  • Bin selber noch anfänger...

    1.code tags
    2.

    int main()
    
    int* eingabe()
    {
    int *ptr = NULL;
    int arr[3] = {1,2,3};
    ptr = &arr[0];//ich glaub hier is der erste Fehler du brauchst das array nicht //zu dereferenzieren
    
    /*cout << "ptr - arr[0]: " << ptr << " *ptr - arr[0]: " << *ptr << endl;
    cout << "ptr - arr[1]: " << (ptr+1) << " *ptr - arr[1]: " << *(ptr+1) << endl;
    cout << "ptr - arr[2]: " << (ptr+2) << " *ptr - arr[2]: " << *(ptr+2) << endl;
    cout << "&arr[0]: " << &arr[0] << " arr[0]: " << arr[0] << endl;
    cout << "&arr[1]: " << &arr[1] << " arr[1]: " << arr[1] << endl;
    cout << "&arr[2]: " << &arr[2] << " arr[2]: " << arr[2]<< endl;*/
    //so hätte ich das gemacht
    for(int i=0;i<3;++i)
    {
       cout<<*(ptr+i)<<"\t"<<"arr["<<i<<"]: " << &arr[i] << endl;
    
    return ptr;
    }
    


  • der compiler sollte bei dem code eigentlich ne warning der art "returning local variable" o.ä. schmeissen.

    dein pointer ptr ist nur innerhalb der funktion eingabe definiert und wird nach beendigung derselben gelöscht bzw. ungültig.

    du bekommst also nen pointer zurück, der auf irgendwas zeigt, aber nicht auf das, was du willst.

    änder deine funktion ab:

    void eingabe(&int);

    und ruf sie dann so auf:

    int *p;
    eingabe(p);
    //.....



  • übrigens:

    ptr = &arr[0];

    sowas ist ok. das ist kein dereferenzieren. das biegt den pointer ptr nur auf das erste element von arr um.



  • pointerman schrieb:

    übrigens:

    ptr = &arr[0];

    sowas ist ok. das ist kein dereferenzieren. das biegt den pointer ptr nur auf das erste element von arr um.

    Is das nicht das gleiche???



  • Hi ihr

    Ich habe dazu auch eine Frage
    kann man wenn man schreibt

    int *p;
    eingabe(p);
    

    dann noch ein

    int *x //also n anderen namen
    

    machen???

    und was steht dann an *p das was man dann später an *p übergibt z.B.

    int* a=3;
    int *p;
    
    int* funktion(int* p)
    {
    p=&a; // wird dann 3 an p übergeben???
    return p;
    }
    

    (Ich Kämpfe nämlich auch gerade mit den Zeigern)

    Klappt das????

    mfg Kevin



  • So erstmal das Programm wie ich denke das es richtig is:

    #include <iostream>
    
    int* eingabe(int *p);
    
    int main()
    {
    	int *p;
    	p=NULL;
    
    	p=eingabe(p);
    
    	for (int i=0;i<3;++i)
    	{
    	    std::cout<<"Addresse: "<<&p+i<<"\tWert: "<<*(p+i)<<"\n";
    	}
    	return 0;
    }
    
    int* eingabe(int *p)
    {
        int arr[3]={1,2,3};
        p=&arr[0];
    
        return p;
    }
    

    Jetzt zu deiner Frage:

    dann noch ein
    C/C++ Code:
    int *x //also n anderen namen
    C/C++ Code:
    int *x //also n anderen namen
    C/C++ Code:
    int *x //also n anderen namen

    machen???

    und was steht dann an *p das was man dann später an *p übergibt z.B.

    C/C++ Code:
    int* a=3;
    int *p;

    int* funktion(int* p)
    {
    p=&a; // wird dann 3 an p übergeben???
    return p;
    }
    C/C++ Code:
    int* a=3;
    int *p;

    int* funktion(int* p)
    {
    p=&a; // wird dann 3 an p übergeben???
    return p;
    }
    C/C++ Code:
    int* a=3;
    int *p;

    int* funktion(int* p)
    {
    p=&a; // wird dann 3 an p übergeben???
    return p;
    }

    (Ich Kämpfe nämlich auch gerade mit den Zeigern)

    Klappt das????

    So geht es nicht (denk ich zumindest), weil der Zeiger die Addresse einer Variablen speichert und nicht deren Wert.

    int a=3;
    int *pa=&a;//funktioniert
    
    int* a=3;
    int* pa=&a;//funtkioniert wohl nicht weil a noch nicht initialisiert wurrde bzw nicht richtig
    


  • @anfänger1:
    also dein programm funkt aber nicht oder? nur das erste element passt. ansonsten gibt er irgendwas aus...

    int* eingabe(int *ptr)
    {
    
    *ptr = 1;
    *(ptr+1) = 2;
    *(ptr+2) = 3;
    return ptr;
    }
    
    void main()
    {
    int *p;
    
    int arr[3];
    p = eingabe(arr);
    
    cout << p << " " << *p << endl <<endl;
    cout << (p+1) << " " << *(p+1) << endl << endl;
    cout << (p+2) << " " << *(p+2) << endl << endl;
    
    }
    


  • Das stimmt...nimm das von Anfänger4 das funktioniert...



  • Anfänger1 schrieb:

    Das stimmt...nimm das von Anfänger4 das funktioniert...

    Nö, da wird ein Zeiger auf ein lokales Array zurückgegeben. Den Inhalt von p gibt es in main nicht mehr.



  • @anfänger4

    Hä wiso jetzt pa dann must du ja erst einen Zeiger namens pa deklarieren.In einer (funktionierendem) Code habe ich das auch mit dem gesehen

    int* a=3;
    int* pa=&a;
    

    Aber nun nochmal wird 3 jetzt an pa übergeben

    meinst du eigentlich bei pa den Präfix für Pointer ???

    mfg Kevin



  • also mal kurz zu pointern:

    pointer sind "zeiger" auf einen bereich im speicher.

    wenn ich mir also so einen pointer anlege

    class A;
    A *ptr_foo;

    dann hab ich c++ erstmal nur gesagt, dass ich hier nen pointer hab, der irgendwann (vielleicht) mal auf nen gültiges objekt zeigt. momentan zeigt der auf irgendwas. in wirklichkeit ist dieser pointer nämlich ein int. und bei meiner deklaration wird er mit irgendnem zufallswert belegt. also sollte ich ihn lieber noch nicht verwenden, da liegt nämlich gar nicht mein objekt auf dem speicher.

    mit dem schlagwort "new" kann ich dann wirklich ein objekt erzeugen.

    ptr_foo = new A();

    nun bekommt foo eine gültige adresse zugewiesen, die auch wirklich auf ein echtes objekt vom typ A zeigt. wundervoll!

    aber man muss "new" ja gar nicht benutzen. ich kann doch auch sowas machen:

    A foo;

    was macht das denn? so ein objekt ist sozusagen "gleich da". ich muss nicht lange im speicher wühlen. das gefällt mir viel besser, also erzeuge ich alle meine objekte nur noch so!

    aber nun hab ich so eine funktion

    void bar(A *foobar);

    und wenn ich die mit meinem schönen einfachen objekt aufruf

    bar(foo);

    , meckert der compiler "can't convert A to int" 😞
    ist ja auch klar, er erwartet hier eine adresse. aha, gabs da nicht so einen referenz operator? genau, das ist das &.
    der besorgt sich von einem objekt die adresse. tolle sache, nun kann ich mir die adresse von foo holen und die funktion trotzdem verwenden!

    bar(&foo);

    und siehe da, es funktioniert.

    und was ist der derreferenzoperator? das ist *. ja, genau derselbe wie der operator, der pointer kennzeichnet. verwirrend? ja. aber er wird anders verwendet.

    A *ptr_foo;
    ptr_foo = new A();

    bar2(A foobar);

    bar2(*(ptr_foo));

    es kommen nämlich klammern um die variable, die dereferenziert werden soll. c++ übergibt der funktion bar2 dann nicht mehr die speicheradresse sondern wirklich das objekt. grosse objekte können viel speicher verwenden und wenn man die dann so benutzt, muss davon ne kopie erstellt werden. das geht auf die performance.

    was würde also sowas machen?:

    int* a=3;
    int* pa=&a;

    zunächst wird eine referenz (pointer) auf ein int erzeugt... nein, wird es nicht! es würde ein pointer erzeugt werden, der im speicher auf die adresse 3 zeigt. oh verdammt, da liegt irgendwelches ganz fieses systemzeugs. also lassen wir sowas lieber gar nicht erst zu, würd nur ganz schlimme sachen verursachen.

    also geht das schonmal nicht. aber was würd denn

    int* pa=&a;

    theoretisch machen? erinnern wir uns, & ist der referenz operator. a ist aber schon eine referenz. was soll davon die referenz sein? vielleicht steht an der stelle, auf die a zeigt noch ne adresse und die will ich haben.
    das lassen wir aber lieber nicht zu. denn mit solchen referenzen kann man ganz grossen schweinkram machen. man kann nämlich z.b. sowas machen:

    ++a;

    nun zeigt a nicht mehr dahin, wo das objekt "anfängt", sondern schon auf die nächste stelle im speicher. also wäre ein aufruf &a absolut nicht nachvollziehbar. lieber weglassen sowas.

    ich will nun aber, dass mein pointer pa auf a zeigt! kein problem, das geht. wir holen uns dazu einfach die adresse wo a anfängt

    pa = &a[0];

    denn das ist definiert, da weiss der doofe compiler auch, wo es lang geht und meckert nicht mehr.

    wir sind also zu dem schluss gekommen, dass

    int* a=3;
    int* pa=&a;

    überhaupt kein gülter c++ code ist.

    aber warum geht denn sowas?

    int *a;
    a = 0;

    ist das nicht dasselbe? nein, denn 0 ist definiert als "dieser zeiger ist noch ungültig".

    so, viel gesülze. vielleicht is was hängengeblieben 😉



  • Wow das ist mal ne Antwort danke

    mfg Kevin



  • Hier im Magazin-Teil gibts auch einen sehr guten Artikel zu Pointern in C/C++.


Anmelden zum Antworten