Pointer - anfaengerproblem



  • Hallo!

    Wie bereits der Titel verrät, habe ich gerade ein wenig verständnisprobleme mit dem Verwenden von Pointern / und Arrays.

    Sagen wir mal ich verwendet folgende Struktur:

    typedef struct {
            int number;
            char *name;
        } element;
    

    Davon möchte ich ein Array von Elementen in Form eines Pointers generieren, also

    int main(int argc, char** argv) {
    int average_num=50;
    
    element *all_elements = (element*) malloc(sizeof(element)*average_num);
    
    //1) Was ist jetzt die Adresse, für welche der Speicher reserviert wurde, ist das
    // printf("%p ", all_elements);   oder  printf("%p ", &all_elements); ???
    
    //jetzt liste füllen
    fill_element_list(all_elements);
    }   
    
    void fill_element_list(element *el_list) {
    
    int index =0;
    BOOL abbrechen;
    
    // ..details lasse ich weg
    
    while(!abbrechen) {
    
    //2) fuelle ich jetzt das array richtig??
    element new_el = {1, "name"};
    
    el_list[index] = new_el;
    
    //3) Und jetzt was ich überhaupt nicht verstehe, was ist jetzt die Adresse meines neuen elements im array, ist das &el_list[index] oder ohne das "&" Zeichen???
    
    index++;
    }
    
    }
    

  • Mod

    element *all_elements = (element*) malloc(sizeof(element)*average_num);
     
    //1) Was ist jetzt die Adresse, für welche der Speicher reserviert wurde, ist das
    // printf("%p ", all_elements);   oder  printf("%p ", &all_elements); ???
    

    Ersteres. Das andere ist die Adresse des Zeigers selbst (ein Zeiger ist auch nur eine Variable und hat eine Adresse).
    Der Cast ist übrigens unnötig und verdeckt eventuell Fehler, die der Compiler sonst finden würde. Den Cast braucht man nur in C++, aber dort würde man weder malloc, noch Pointer, noch einen C-Cast benutzen, es ist bloß aus historischen Gründen möglich, C in C++ zu machen.

    //2) fuelle ich jetzt das array richtig??
    element new_el = {1, "name"};
    
    el_list[index] = new_el;
    

    Prinzipiell ist dieser Code technisch korrekt (wird übersetzt) und wird auch funktionieren, aber ich befürchte, das ist eher Zufall. Falls du es nicht weißt: Zeichenketten in C (oder auch allgemein: Arrays) funktionieren ganz anders als in vielen anderen Sprachen. In anderen Sprachen kann man ihnen Werte zuweisen und diese Werte werden dann kopiert. In C ist das nicht so. Falls dir das neu ist: Dringend Grundlagen von Zeichenketten in C angucken! Sonst fliegt dir dieser Code um die Ohren, sobald du auch nur kleine Änderungen vor nimmst.
    Falls das für dich ein alter Hut ist, ignoriere diesen Hinweis. Aber wenn du das schon wüsstest, würdest du vermutlich diese Fragen nicht stellen 🙂 .

    //3) Und jetzt was ich überhaupt nicht verstehe, was ist jetzt die Adresse meines neuen elements im array, ist das &el_list[index] oder ohne das "&" Zeichen???

    Ja, das Element steht jetzt an &el_list[index] . Es ist aber nicht wirklich neu, denn es wurde ja schon in Zeile 4 erstellt. Du hast ihm bloß einen neuen Wert zugewiesen.
    &el_list[index] ist übrigens nach den Regeln der Pointerarithmetik auch das gleiche wie el_list + index .



  • Hallo!

    Erst mal vielen vielen Dank für die ausführliche Antwort!

    - das mit den Strings ist mir schon bekannt, meine eigentliche Struktur sieht auch ganz anders aus, habe nur schnell ein Beispiel hier gemacht, und das mit den char array nicht beachtet

    SeppJ schrieb:

    element *all_elements = (element*) malloc(sizeof(element)*average_num);
     
    //1) Was ist jetzt die Adresse, für welche der Speicher reserviert wurde, ist das
    // printf("%p ", all_elements);   oder  printf("%p ", &all_elements); ???
    

    Ersteres. Das andere ist die Adresse des Zeigers selbst (ein Zeiger ist auch nur eine Variable und hat eine Adresse).
    Der Cast ist übrigens unnötig und verdeckt eventuell Fehler, die der Compiler sonst finden würde. Den Cast braucht man nur in C++, aber dort würde man weder malloc, noch Pointer, noch einen C-Cast benutzen, es ist bloß aus historischen Gründen möglich, C in C++ zu machen.

    - ok also hier kann ich dann einfach:

    element *all_elements;
    

    - die Adresse, wo dann die Elemente abgelegt werden ist dann &all_elements? Tut mir leid, dass ich nochmal frage, das hast du ja bereits unten für das jeweilige element geantwortet (.. &all_elements[index] ..) aber bin mir nicht sicher, da ja hier noch ein leeres array ist. Und der Pointer ja wie du sagst, eine Adresse speichert, dann müsste ja die Adresse wo die Elemente später abgelegt werden einfach der pointer sein oder nicht? - also (printf(%p), *all_elements) ?



  • Noch ein kurzer edit zu meiner letzte frage:

    - mit "&" kriegt man doch die Adresse des Elements, ich würde ja dann eigentlich mit:

    &all_elements

    die Adresse kriegen, wo mein Pointer an sich gespeichert ist, und nicht die Adresse, wo meine Elemente mit denen ich das Array später fülle gespeichert werden. Oder lieg ich hier ganz falsch :S



  • Das ist richtig.

    So ist der erste Satzt von SeppJs Antwort zu verstehen.



  • //2) fuelle ich jetzt das array richtig??
    element new_el = {1, "name"};
    
    el_list[index] = new_el;
    

    Ab C99 oder ab MSVC 2013 kann man auf die Hilfsvariable mit Initialisierung verzichten und compound literals benutzen:

    el_list[index] = (element){1, "name"};
    

Anmelden zum Antworten