Dümmlingsfrage: lokale Pointer und der zugehörige Speicher



  • Grüß Gott..

    Das ist mir jetzt schon ziemlich unangenehm, weil die Frage mit Sicherheit die meisten hier beim Überfliegen des Politikteils der Süddeutschen beantworten könnten, ohne Ihre Lektüre zu unterbrechen...

    Angenommen, ich habe ein global deklariertes und vorinitialisiertes struct relativ geringen Ausmaßes in Form eines Arrays angelegt und möchte später in einer Funktion in etwa folgendes tun:

    void switch_members (struct MySTR *mem1, struct MySTR *mem2)
    {
       struct MySTR *memtmp = mem1;
       mem1 = mem2;
       mem2 = memtmp;
    }
    

    Die meisten unter Euch haben genug Phantasie, zu erkennen was ich vorhabe 🙂

    Nun beschäftigen mich im Grunde 2 Fragen:

    1. Tauscht diese Funktion nun einfach die Speicheradressen der beiden Pointer untereinander aus und damit herrscht grobe Unordnung in meinem Array bzw. wäre es wohl geschickter, mal außen vor, dass das Array eh global ist, dieses zu übergeben, die beiden Indizes der zu tauschenden Members und das dann wie folgt zu tun? ->
    void switch_members (struct MySTR *strArr[], int i, int y)
    {
       struct MySTR *memtmp = strArr[i]; // oder &strArr[i]? Ich Dümmling... -.-
       strArr[i] = strArr[y];
       strArr[y] = memtmp; // oder *memtmp? DoppelDümmling :-/
    }
    

    Oder hätte das im Grunde den selben Effekt wie oben? Wie sähe es aus, wenn ich keinen Pointer auf das Array übergebe, sondern einfach direkt die Elemente des globalen Arrays anspräche?

    1. in beiden genannten Fällen verwende ich ja einen auf die Funktion begrenzten Pointer auf ein MySTR. Muss ich mich da selbst um's "Aufräumen" kümmern? Oder wird in diesen genannten Fällen sowieso nur die Information über die Speicheradresse ausgetauscht und damit kein weiterer Speicherplatz irgendwo benutzt, der freigegeben werden müsste?

    Danke für Eure zahlreichen und nicht-vernichtenden Antworten 😉



  • Im ersten Beispiel tauscht du nur die lokalen Zeiger mem1 und mem2. In der globalen Struktur passiert da nichts.

    struct MySTR *strArr[] ist eine ARRAY mit Zeigern auf deine Struct.
    Willst du nicht haben. Du hast einfach ein Array

    void switch_members (struct MySTR strArr[], int i, int y)
    {
       struct MySTR memtmp;
    
       memtmp = strArr[i] ;
       strArr[i] = strArr[y];
       strArr[y] = memtmp; 
    }
    


  • DirkB schrieb:

    Im ersten Beispiel tauscht du nur die lokalen Zeiger mem1 und mem2. In der globalen Struktur passiert da nichts.

    struct MySTR *strArr[] ist eine ARRAY mit Zeigern auf deine Struct.
    Willst du nicht haben. Du hast einfach ein Array

    void switch_members (struct MySTR strArr[], int i, int y)
    {
       struct MySTR memtmp;
       
       memtmp = strArr[i] ;
       strArr[i] = strArr[y];
       strArr[y] = memtmp; 
    }
    

    Dankeschön, DirkB 🙂
    Bei Arrays nimmt's sich ja nicht wirklich was, ob ich als Parameter nun strArr[] oder *strArr verwende, oder? Wobei natürlich die Verwendung der Indizes in Verbindung mit der Angabe als Array etwas geradliniger aussieht, würde ich meinen 🙂

    Oder bin ich da wieder mal schief gewickelt?



  • Pretty schrieb:

    Oder bin ich da wieder mal schief gewickelt?

    Nein.

    ~Du bist nicht schief gewickelt.~



  • Noch was dümmliches:

    Kann ich unter den meisten Umständen davon ausgehen, dass ein Array mit 10.000 deklarierten und vorinitialisierten Elementen à 200 Bytes sequenziell im Speicher liegt? Bzw. führt ein

    memset (meinStructArr, '\0', sizeof (meinStructArr));
    

    mit an Sicherheit grenzender Wahrscheinlichkeit dazu, dass die Attribute aller structs meinStruct im Array meinstructArr[] nun auf '\0' stehen?
    Gibt's außer der Anzahl an Codezeilen da einen Unterschied zu einer Schleife, die die einzelnen meinStructs abarbeitet?



  • Pretty schrieb:

    Kann ich unter den meisten Umständen davon ausgehen, dass ein Array mit 10.000 deklarierten und vorinitialisierten Elementen à 200 Bytes sequenziell im Speicher liegt? Bzw. führt ein

    memset (meinStructArr, '\0', sizeof (meinStructArr));
    

    mit an Sicherheit grenzender Wahrscheinlichkeit dazu, dass die Attribute aller structs meinStruct im Array meinstructArr[] nun auf '\0' stehen?
    Gibt's außer der Anzahl an Codezeilen da einen Unterschied zu einer Schleife, die die einzelnen meinStructs abarbeitet?

    Du kannst mit Sicherheit davon ausgehen, dass die Elemente aufeinander folgend sind.

    Bei einem statischen Array geht das auch gleich bei der Definition

    struct MySTR strArr[10000] = {0};
    

    Nur belastet so ein großes Array ganz erheblich deinen Stack.
    Besser dynamisch:

    struct MySTR *meinStructArr = malloc(sizeof(struct MySTR) * 10000);
    // Noch prüfen ob meinStructArr != NULL
    memset (meinStructArr, 0, sizeof (meinStructArr)*10000)
    .....
    free(meinStructArr);
    

    Bis auf das sizeof() und free () merkst du in der Handhabung keinen Unterschied.



  • DirkB schrieb:

    Besser dynamisch:

    Also wann immer es geht würde ich den Stack vorziehen. Selbst wenn man von einem großen struct mit 50 Byte ausgeht, sind 50000 Byte immer noch besser auf dem Stack aufgehoben. Hehe dachte arr[1000] oO
    Zudem würde sich calloc() doch irgendwie anbieten, wenn man eh alles mit 0en initialisieren will?



  • 1000 Dank Ihr beiden... Daran hatte ich natürlich gar nicht gedacht...



  • cooky451 schrieb:

    Zudem würde sich calloc() doch irgendwie anbieten, wenn man eh alles mit 0en initialisieren will?

    Klar!
    Aber ich wollte doch zeigen wie man den Bereich mit memset löscht. 😉



  • DirkB schrieb:

    Aber ich wollte doch zeigen wie man den Bereich mit memset löscht. 😉

    Ach so 🙂


Anmelden zum Antworten