Anfängerfrage zu Pointern



  • Phaeton schrieb:

    Die Frage im Buch lautet, wo der "grundlegende Fehler" ist.
    Meiner Meinung nach besteht einmal ein Druckfehler: Die while-Schleife wird 0-mal durchlaufen.

    Jupp. Soll das schon der "grundlegende Fehler" sein? Einen anderen seh ich beim besten Willen nicht. pi hätte mit new int(0) initialisiert werden müssen.

    Der zweite (eigentliche) Fehler scheint mir, dass in Zeile 5 vor "pia[*pi] = *pi;" der Inhalts-Operator '*' fehlt.
    Als ich aber später ein wenig im Compiler experimentierte, kam ich zu dem Schluss, dass ein Pointer, der auf ein Array zeigt, irgendwie nicht dereferenziert werden muss.
    Wie man merkt, bin ich etwas verwirrt 😃

    Du meinst, vor pia hätte noch ein Stern gemusst? Nein: a[b] bedeutet *(a+b), d.h. Array-Zugriff ist Dereferenzierung. Das ist eigentlich alles, was man dazu wissen muss. Wenn man Pointerarithmetik verstanden hat, versteht man auch Arrays. Und umgekehrt.



  • Phaeton schrieb:

    2. Kann mir jemand erklären, wie die Pointer funktionieren, die auf ein Array weisen (z.B. "int *pia = new int [4]") ?

    Diese Pointer funktionieren genau gleich, wie ein "normaler" Pointer. Arrays selbst sind eigentlich auch Pointer, weil

    char *ptr; //...
    *(ptr + 2) = 0;
    ptr[2] = 0;
    2[ptr] = 0;
    

    intern genau dieselbe Bedeutung hätte, wie wenn ptr als

    char ptr[];
    

    deklariert würde. In deinem Beispiel bedeutet int *pia = new int[10], dass dein Zeiger auf das erste Element des angeforderten Speichers zeigt. Mit pia[n], n[pia] & *(pia + n) greifst du auf das n-te Element zu. Der Rest sollte dir bekannt sein. Achja, unter Pointer, die auf Arrays verweisen versteht man eher Dinge wie char *argv[] und das. Aber es steckt das gleiche dahinter...

    mfg



  • Oh, CanDL, ich muss dir heftigst widersprechen!
    Mit

    char *ptr; //...
    *(ptr + 2) = 0;
    ptr[2] = 0;
    2[ptr] = 0;
    

    greift man in der letzten Zeile auf garnichts zu, damit holt man sich nur Compilerfehler ins Haus.
    Und wenn man es so versucht

    char *ptr; //...
    int a = 2;
    *(ptr + a) = 0;
    ptr[a] = 0;
    a[ptr] = 0;
    

    wird es ebenfalls spätestens bei der letzten Zeile Proteste hageln. 👎

    [edit]Oh mann, ist mir grad gar nicht so aufgefallen: Du würdest hier sowieso auf Speicher rumhackstücken, der dir nicht gehört! Pfui, pfui, pfui![/edit]



  • Deadlef schrieb:

    Mit

    char *ptr; //...
    *(ptr + 2) = 0;
    ptr[2] = 0;
    2[ptr] = 0;
    

    greift man in der letzten Zeile auf garnichts zu, damit holt man sich nur Compilerfehler ins Haus.

    Das ist falsch. Bashar hat's oben erklärt. Wenn das so wäre wie Du sagst, dann wäre Addition nicht mehr kommutativ.

    Und wenn man es so versucht

    char *ptr; //...
    int a = 2;
    *(ptr + a) = 0;
    ptr[a] = 0;
    a[ptr] = 0;
    

    wird es ebenfalls spätestens bei der letzten Zeile Proteste hageln.

    Aber nicht vom Compiler.

    Oh mann, ist mir grad gar nicht so aufgefallen: Du würdest hier sowieso auf Speicher rumhackstücken, der dir nicht gehört! Pfui, pfui, pfui!

    Das ist zur Abwechslung mal richtig, allerdings lässt der '//...' in Beispielcode (im Forum) vermuten, daß da 'etwas sinnvolles' steht.



  • Ahem, hast du die letzte Zeile mal dem Compiler gegeben ??? Ich hab VC 7.1 Pro, und der frisst das genau wie es da steht (ohne Warnung). Mit dem Edit hast du schon Recht, aber das war in meinem Post nicht von Bedeutung. Es ging darum, wie man auf die Elemente eines Arrays zugreifen kann und nicht wie man einen initialisiert. Ausserdem war da hinter dem char *ptr ein Kommentar mit der Andeutung, das dazwischen noch etwas kommt. Gib mal folgendes ein und compiliere :

    int main()
    {
    	char *Data = new char[0xff];
    	2[Data] = '\0';
    	delete[] Data;
    }
    

    Wenn dein Compiler das nicht annimmt, besorg dir einen besseren.

    Deadlef schrieb:

    Und wenn man es so versucht

    char *ptr; //...
    int a = 2;
    *(ptr + a) = 0;
    ptr[a] = 0;
    a[ptr] = 0;
    

    wird es ebenfalls spätestens bei der letzten Zeile Proteste hageln.

    Ach ja ? Hmm, warum sagt mir denn mein Compiler nichts, wenn ich

    int main()
    {
    	int Index = 0xf;
    	char *Data = new char[0xff];
    	Index[Data] = '\0';
    	delete[] Data;
    }
    

    reinlasse ? Hast du das ausprobiert, bevor du mir diese Vorwürfe gemacht hast ?

    mfg





  • Danke für die vielen Infos! Manches kann ich zwar nicht ganz nachvollziehen, weil es im Buch noch nicht vorgekommen ist, aber ich habe verstanden 😉 . Nur zur Zusammenfassung: Ein Zeiger der auf ein Array weist, unterscheidet sich in der Handhabung praktisch nicht von einem statischen Array (außer, dass man mit delete[] den Speicher freigeben sollte). D.h. man muss sie nicht derefenzieren.
    Wieso ist das eigentlich so geregelt, ist doch eigentlich unlogisch? (Und wieso wird im Buch darauf nicht hingewiesen?)

    Achja, die Übung im Buch läuft wirklich nur darauf hinaus, dass es eigentlich

    int *pi = new int(10);
    

    heißen sollte? Das wäre ja wirklich banal...



  • Ich meinte natürlich

    int *pi = new int(0);
    


  • OK, Leute, tut mir leid, aber das klang für mich einfach viel zu völlig abgedreht, als dass das hätte funktionieren dürfen. Aber ich bleibe trotzdem bei meinem edit: einem Anfänger legt doch nicht solchen Code hin, mit dem er sich Speicherfehler noch und nöcher baut.
    Ansonsten: Ja, natürlich frisst der Compiler das, hab es halt nicht ausprobiert. 🙄



  • Folgende Vergleichbarkeit (vertikal übereinander) ist gegeben:

    &pi    pi    *pi // Zeiger auf int
    &pa    pa    *pa // Zeiger auf array
    

    jetzt gilt bezüglich des Arrays nur Folgendes:

    pa = &pa[0]
    *pa =  pa[0]
    

    Zeiger auf Variablen im Heap werden mit new angelegt und mit delete freigegeben.
    Zeiger auf dynamische Arrays im Heap werden mit new ... [] angelegt und mit delete[] freigegeben.

    http://www.cpp-tutor.de/cpp/le11/le11_01.htm


Anmelden zum Antworten