dyn. Speicher in Funktion



  • Hallo,
    ich würde gerne eine Funktion, welche ein dyn. Feld vergrößert und Werte darin ändert erstellen. Allerdings funktioniert das Programm nur wenn ich mit integer-Werten arbeite. Sobald ich statt "int" "double" nehme geht das nicht mehr (es werden bei den meisten Durchläufen fast alle Werte auf 0 gesetzt, Ausgabe habe ich aber angepasst). Ich weiß leider überhaupt nicht weshalb. Wäre nett, wenn mir da jmd helfen könnte.
    mfG

    #include <stdio.h>
    #include <stdlib.h>
    
    void erweitern (int *array)
    {
        array = (int*) realloc(array, 10*sizeof(int));
    
    if (array == NULL)
    {
        printf("kein Speicher (funktion)\n");
    }
    
    
    else
    {
        array [9] = 21332;
        array [7]  = 9999;
        array [8]  = 44444;
        array [6]  = 11111;
        array [5]  = 11111;
        array [3] = 200;
    }
    
    
    }
    
    
    int main()
    {
    
        int *array;
    
        array =  (int*)calloc(5, sizeof(int));
    
        if (array == NULL)
        {
            printf("kein Speicher\n");
    
            return 1;
        }
    
    else
    {
    
    
        for (int i=0; i<5;i++)
        {
            array[i] = i;
    
            printf("%d:  %d\n",i, array[i]);
        }
    }
    
     erweitern(array);
    
    
    printf ("neu\n\n");
    
    for (int i=0; i<10;i++)
        {
    
            printf("%d:  %d\n",i, array[i]);
        }
    
    free (array);
    
        return 0;
    }
    
    


  • So sollte es klappen:

    erweitern(&array);
    und der Funktionskopf sollte so aussehen
    erweitern(int **array){
       *array = (int*) realloc(*array, 10*sizeof(int));
    
    ...
    }
    

    Bei einem Funktionsaufruf werden die Werte auf dem Stack gelegt und die Adresse deines Ursprünglichen Ptrs wieder erstellt. So dass du auf den gleichen Speicherbereich zeigst. Wir vor deinem Aufruf von erweitern


  • Mod

    Die Casts der (x)alloc-Rückgabewerte sind unnötig und kontraproduktiv, dies ist C, nicht C++.

    Du hast auch das klassische realloc-Speicherloch (das jeder einmal hat, bevor man es erklärt bekommt): Schlägt realloc fehl (Rückgabewert NULL), dann ist der ursprüngliche Speicher immer noch belegt (und hat auch noch die Originalwerte drin). Du hast dann aber gerade mit *array = realloc(*array, 10*sizeof(int)); gerade die letzte Referenz auf diesen Speicher überschrieben und kannst ihn somit nie wieder freigeben. Die korrekte Benutzung von realloc ist:

    1. realloc durchführen, Rückgabe in einer temporären Variable speichern
    2. Prüfen, ob Rückgabe NULL ist
      • Nein: Alles in Ordnung, Originalreferenz mit dem Ergebnis überschreiben
      • Ja: Originalreferenz NICHT überschreiben. Sie muss im weiteren Programmverlauf noch freigegeben werden.


  • @pmqtt sagte in dyn. Speicher in Funktion:

    So sollte es klappen:
    erweitern(&array);

    Oder du machst es wie die anderen alloc Funktionen auch und gibst den neuen Wert einfach als Rückgabewert zurück.



  • @DirkB Ich fand es ziemlich lehrreich zu verstehen, wie das mit den pointern und Funktionsaufrufe funktioniert. Dies ist erstmal so nicht ganz einsichtig. Denn für gewöhnlich fühlt sich ein Pointer als Parameter, wie eine in/out parameter an.

    Grüße


  • Mod

    @pmqtt sagte in dyn. Speicher in Funktion:

    @DirkB Ich fand es ziemlich lehrreich zu verstehen, wie das mit den pointern und Funktionsaufrufe funktioniert. Dies ist erstmal so nicht ganz einsichtig. Denn für gewöhnlich fühlt sich ein Pointer als Parameter, wie eine in/out parameter an.

    Ganz einfach: Du willst den Pointer verändern, also als in/out-Parameter haben. Daher brauchst du einen Pointer auf den Pointer.



  • @SeppJ Wenn man es weiß, ist fast alles einfach. Ich meinte nur wenn man ganz am Anfang steht ist das rumexperimentieren mit solchen Konstrukten doch ein tolles mittel


Log in to reply