Speicherreservierung in Funktion mittels malloc



  • Hi,

    kann mir jemand sagen, ob ich die Speicherreservierung innerhalb einer Funktion so durchführen kann?

    char * speicher_fuer_charptr_alloziieren(char* ptr)
    {
       char buffer[20];
    
       fgets(buffer, 20, stdin);
    
       ptr = malloc(strlen(buffer)+1) 
    
       strcpy(ptr, buffer); 
    
       return ptr;
    }
    

    main.cpp

    char* ptr;
    
        ptr = speicher_fuer_charptr_alloziieren(ptr);
    
       printf("%s", ptr);
    

    Gibt es noch eine bessere Möglichkeit wenn ich eine Namenslistenarray einlesen möchte, dass ich über ptr verwalte? (char * namensliste[20])

    Wenn ich den buffer mit malloc anlegen würde und dann den Wert der Adresse zurückgebe würde es ja einen Fehler verursachen, weil der Speicherplatz flüchtig ist oder?

    mit freundlichen Grüßen,

    matze



  • MatzePotrow schrieb:

    Hi,

    kann mir jemand sagen, ob ich die Speicherreservierung innerhalb einer Funktion so durchführen kann?

    Ja, kannst du.
    Aber warum übergibst du noch ptr an deine Funktion?

    MatzePotrow schrieb:

    Gibt es noch eine bessere Möglichkeit wenn ich eine Namenslistenarray einlesen möchte, dass ich über ptr verwalte? (char * namensliste[20])

    Worauf soll da denn ptr zeigen?

    MatzePotrow schrieb:

    Wenn ich den buffer mit malloc anlegen würde und dann den Wert der Adresse zurückgebe würde es ja einen Fehler verursachen, weil der Speicherplatz flüchtig ist oder?

    Nö. Wo ist denn der unterschied zu ptr
    Das ist ja der Vorteil von dynamischen Speicher.

    Du darfst aber das free nicht vergessen.



  • Also einfach:

    char * speicher_fuer_charptr_alloziieren()
    {
       ptr = malloc(21)
       fgets(ptr, 20, stdin);
    
       return ptr;
    }
    


  • fgets weiß von der '\0' und plant sie mit ein.
    Es ist also nicht nötig mehr Speicher zu allokieren.
    Problematischer könnte das '\n' sein.

    (Bei scanf ist das anders)



  • DirkB schrieb:

    Worauf soll da denn ptr zeigen?

    auf die einzelnen char ptr des arrays.

    for(i = 0; i <= 19; i++)
    
    namensliste[i] = speicher_fuer_charptr_alloziieren(char* ptr)
    

    DirkB schrieb:

    War auch nur ein Beispiel.
    Aber warum übergibst du noch ptr an deine Funktion?

    Nö. Wo ist denn der unterschied zu ptr
    Das ist ja der Vorteil von dynamischen Speicher.

    Ist es nicht eine Grundregel, dass man keine lokalen Adressen aus einer Funktion zurückgibt ?

    z.B.

    int* wert_per_adresse_zurueckgeben()
    {
        int i = 7; 
    
        return &i; 
    }
    

    Sowas darf ich doch nicht machen, da ich hier eine Adresse einer lokalen variable zurückgebe, die nach dem verlassen der Funktion wieder vom stack verschwindet ?

    Wieso kann ich das jetzt bei malloc machen ?

    Also ich lege mittels malloc einen Speicherplatz an und erhalte die Anfangsadresse des Speicherplatzes. Aber wenn ich jetzt die Funktion verlasse, veschwindet diese doch auch wieder vom stack ?

    Das ist auch der Grund warum ich einen char *ptr übergeben habe, um innerhalb der Funktion mittels call by reference auf ptr zuzugreifen.

    Belli schrieb:

    Also einfach:
    [code="c"]char * speicher_fuer_charptr_alloziieren()
    {
    *char ptr = malloc(21);
    fgets(ptr, 20, stdin);

    return ptr;
    }
    [/code]

    Gerade ausprobiert und es funktioniert so. Danke (Flüchtigkeitsfehler ausgebessert). Wobei es mir jeodch immernoch unklar ist warum dies fehlerfrei möglich ist.



  • In C werden Kopien der Werte an Funktionen übergeben und auch zurückgegeben.

    Was in C als "call by reference" bezeichnet wird, ist auch ein "call by value". Du als Programmierer übergibst die Adresse.

    Du gibst beim malloc-Beispiel den Inhalt vom Pointer zurück. Und das ist die Adresse die du von malloc bekommst.
    Der Speicher, der von malloc verewaltet wird, bekommt überhaupt nicht mit, dass du die Funktion verlassen hast.

    char * speicher_fuer_charptr_alloziieren(char* ptr)
    { // hier ist ptr eine lokale Variable.
       ..
       return ptr;
    }
    

    Für das verhalten ist das nichts anderes als

    char * speicher_fuer_charptr_alloziieren()
    { // so wie hier
       char* ptr;
     ...
    
       return ptr;
    }
    

    Und

    int* wert_per_adresse_zurueckgeben(int i)
    {
        return &i;
    }
    

    geht auch nicht, da i eine lokale Variable ist.

    Ein Pointer ist eine Variable, die eine Adresse speichert. Und diese Adresse wird als Kopie weiter gegeben.


Log in to reply