[gelöst] dynamische Speicheranforderung auslagern



  • Hallo zusammen.

    Habe schon gesucht aber unverständlicher Weise nix auf die Schnelle gefunden.

    Wenn ich Speicher in einer ausgelagerten Funktion allokiere und den Zeiger auf den reservierten Bereich an den Aufrufer zurückgebe, entspricht das dann richtiger Programmierung oder lässt man das - funktionieren tut es ja, aber das muss ja nix heißen.

    Danke schön
    Gruß
    Kai


  • Mod

    Es ist insofern "richtig", als dass es funktioniert. Ob es gut ist, hängt von der Aufgabe deiner Funktion ab. Guter Stil ist, das die gleiche Logikebene des Programms, die eine Ressource anfordert, diese auch wieder frei gibt.



  • würde also bedeuten, dass es richtiger ist, wenn die Freigabe auch wieder in der Funktion erfolgt in der derselbe Bereich reserviert wurde?



  • Hatte auch vorhin mal diesen Ansatz verfolgt:

    ...
      func(hwndText, txtInhalt);
    ...
    
    void func(HWND hwnd, LPWSTR buffer)
    {
      txtInhalt = malloc(... ;
    
      ...
    }
    

    Allerdings steht an der Stelle txtInhalt, nach dem Funktionsaufruf nichts mehr, obwohl ihm in der Funktion der Textinhalt zugewiesen wird.

    Das verstehe ich jetzt nicht so ganz. Geht hier die Reservierung flöten?



  • _Bongo schrieb:

    ...entspricht das dann richtiger Programmierung...
    ...funktionieren tut es ja, aber das muss ja nix heißen...

    2 geniale Erkenntnisse und das bei einem Anfänger, sowas gab hier lange nicht.

    Prinzipiell wurde die Antwort schon gegeben, die eigentliche Datenverarbeitung ist von der Speicherreservierung zu trennen, das entspricht dann "richtiger Programmierung".
    Dazu gehört, dass man als erstes seine Funktionen entsprechend deklariert, d.h. sie bekommen einen Zeiger auf den zuvor und außerhalb der Funktion reservierten Speicher übergeben und evtl. auch noch die Größe.
    Der aufrufende Kontext kümmert sich dann um die weitere Speicherbehandlung, z.B. mit free.
    Also in etwa:

    char *firstString(const char *string, char *speicher)
    {
      sscanf(string,"%99s",speicher);
      return speicher;
    }
    ...
    dann wahlweise die Speicherreservierung:
    
    char s[100];
    char *x = firstString("123 abc",s);
    puts(x);
    
    void *s = malloc(100);
    char *x = firstString("123 abc",s);
    puts(x);
    free(s);
    
    char *x = firstString("123 abc",(char[100]){0});
    puts(x);
    

  • Mod

    _Bongo schrieb:

    würde also bedeuten, dass es richtiger ist, wenn die Freigabe auch wieder in der Funktion erfolgt in der derselbe Bereich reserviert wurde?

    Das habe ich nicht gesagt. Logikebene != eine konkrete Funktion. malloc und free sind auch nur ganz normale Funktionen. Aber sie bilden ein Paar, dass der Nutzer aufruft, um eine Ressource zu reservieren und wieder frei zu geben.

    Beispiel für falsches Vorgehen:
    Deine Funktion holt Speicher für ihr Ergebnis mit malloc, schreibt da Daten rein, und erwartet dann, dass der Nutzer hinterher den Speicher mit free freigibt.

    Besser:
    Sich vom Nutzer passenden Speicher für das Ergebnis geben lassen.

    Oder auch gut, bei komplexen Anwendungen möglicherweise besser:
    Selber einen Handle-Datentypen für die von deiner Anwendung benutzten Ressourcen anbieten. Mit einer Funktion, die solch ein Ding erzeugt; Funktionen, die darauf arbeiten; und einer Funktion, die alles wieder freigibt. Also selber so etwas wie die malloc/free-Infrastruktur. Bei malloc/free ist void* der Handletyp; dynamischer Speicher die Ressource; malloc und free die Funktionen zur Reservierung und Freigabe; und so ziemlich alle Funktionen der Standardbibliothek, die Speicher brauchen, arbeiten mit void*. Ein anderes Beispiel sind Dateien, mit FILE* als Handletyp; offenen Dateien als Ressource; fopen und fclose zur Reservierung und Freigabe; und all den firgendwas-Funktionen aus der Standardbibliothek zur Benutzung. Da dran sieht man schön, dass solch ein System nicht auf Speicher beschränkt ist, sondern für viele Arten von Ressourcen funktioniert und auch benutzt werden solle.



  • Alles klar. Das hilft mir weiter.

    Ich danke Euch
    Grüße


Anmelden zum Antworten