Wie kann ich ein ganzes Array freigeben, dessen Elemente durch Aufrufe von malloc / calloc [duplicate] individuell Speicher zugewiesen wurden?

Aug 16 2020

Nach meinem Wissen sind malloc und calloc nur Buchhaltungs-APIs für den zugrunde liegenden Speicher. Vor diesem Hintergrund frage ich mich, ob ein Aufruf von free () ein ganzes Array freigibt, dessen einzelnen Elementen durch unabhängige Aufrufe von malloc (oder calloc) Speicher zugewiesen wurde.

Genau, ich habe den folgenden Code:

int *num,* num_start;

num_start=num;

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

free(num_start);

Wird free(num_start)das gesamte Array von N ganzzahligen Elementen, denen dynamisch Speicherplatz zugewiesen wurde, unabhängig voneinander freigegeben?

Antworten

1 P__JsupportswomeninPoland Aug 16 2020 at 10:09

Der von Ihnen gepostete "Code" macht keinen Sinn und ist falsch.

int *num, num_start;
num_start=num;

num_start ist eine Ganzzahl, kein Zeiger.

for(i=0;i<N;i++)
{
    num = (int *)calloc(0, sizeof(int));
    num++;
}

Um ehrlich zu sein, verstehe ich nicht, was dieser Code tun soll, aber sicher ist es falsch

Wenn Sie Speicher für NGanzzahlen zuweisen möchten

int *num = calloc(N, sizeof(*num));

und zum befreien brauchst du nur

free(num);

Oder wenn Sie einen Zeiger zum Speichern von N Zeigern auf N Ganzzahlen zuweisen möchten

int **allocate(size_t N)
{
    int **num = malloc(N * sizeof(*num));
    for(size_t i=0; i<N; i++)
    {
        num[i] = calloc(N, sizeof(**num));
    }
    return num;
}

void arrayfree(int **num, size_t size)
{
    for(size_t i = 0; i < size; i++)
    {
        free(num[i]);
    }
    free(num);
}

Wenn Sie Speicher zuweisen, müssen Sie überprüfen, ob der Vorgang erfolgreich war. Diese Überprüfungen sind im Beispiel nicht enthalten, um das Lesen des Codes zu erleichtern.

tadman Aug 16 2020 at 09:55

Die Funktionen calloc()und malloc()geben einen Zeiger auf die Zuordnung zurück, der gleichzeitig als Handle zum Freigeben dieses Speichers dient. Während Sie frei sind, Kopien dieses Zeigers zu erstellen und diese nach Belieben zu bearbeiten, müssen Sie beim Aufrufen free()den ursprünglichen Wert angeben .

Das heißt, das funktioniert:

// Original allocation
int* x = calloc(42, sizeof(int));

// Making a new (independent) copy of the pointer to a new pointer
int* p = x;

// Arbitrary pointer manipulation and mangling
x++;

// Freeing with the copied value
free(p);

Sie können auch ein bisschen abenteuerlustig werden, solange Sie zu Ihrem ursprünglichen Ziel zurückkehren:

int* x = calloc(42, sizeof(int));

x += 40;
x -= 30;
x += 10;
x -= 13;
x -= 7;

free(x);

Wo hier xnach einer kurzen Reise zu seinem ursprünglichen Wert zurückgekehrt ist. In der Regel ist es besser, den ursprünglichen Zeiger beizubehalten, als ihn später rekonstruieren zu müssen. Erstellen Sie Kopien, wenn Sie diese bearbeiten möchten.