Свободный массив структур - PullRequest
0 голосов
/ 11 апреля 2020
#include<stdlib.h>
#include <stdio.h> 
#include <string.h> 

struct t {

    int value;
};

int main (void) {

    struct t *a = malloc(6*sizeof(struct t));
    struct t *b = malloc(sizeof(struct t));

    struct t *c = malloc(sizeof(struct t));
    c->value = 100;
    struct t *d = malloc(sizeof(struct t));
    d->value = 100;
    struct t *e = malloc(sizeof(struct t));
    e->value = 100;

    memcpy(b, a, sizeof(*a));

    int j = 0;

    while (j<6){
        a[j] = *c;
        j++;
    }


    int t = 0;
    while(t < 6){
        free(&a[t]);
        t++;
    }


    free(a);

}

Я пытаюсь освободить элементы внутри массива один за другим. Но этот код не может быть запущен, поэтому я думаю, что что-то может быть не так со свободным во втором, пока l oop. После того, как я изменил второе, в то время как l oop на:

    while(t < 6){
        printf("%d",a[t].value);
        t++;
    }

Это будет работать. Любая идея, как я могу освободить эти элементы? Спасибо!

Ответы [ 3 ]

2 голосов
/ 11 апреля 2020

Я пытаюсь освободить элементы внутри массива один за другим. Но этот код не может быть запущен, поэтому я думаю, что что-то может быть не так со свободным во втором, пока l oop.

Да, неправильно то, что вы пытаетесь освободить элементы один за другим.

Вы не можете освободить выделенную память в других разделах, чем она была выделена. Аргумент free() должно быть значением указателя, которое было ранее получено из функции распределения (а не освобождено). Вызов free() освободит весь блок. Он не видит каких-либо подразделений этого блока, которые вы можете использовать, и вряд ли сможет почтить их, даже если он их увидит.

Есть идеи, как мне освободить эти элементы?

Освободите весь блок сразу, как только вы закончите со всеми данными в нем. То есть просто

free(a);

(а также free(b), free(c), et c.)

1 голос
/ 11 апреля 2020

Один бесплатный за блокировку c d. Когда вы mallo c, вы не захватываете память для каждой структуры. Вы захватываете один блок (за вызов mallo c), который оказывается достаточно большим, чтобы вместить 6 структур для a и 1 структуру каждый для остальных. Вы можете освободить только каждый блок этого блока сразу. В этом случае вы должны освободить сквозной e (то есть адреса, возвращаемые mallo c при условии, что у вас достаточно памяти).

Вы можете, если вам действительно нужно, mallo c массив struct * тогда mallo c блокирует эти структуры *, но зачем вам в этом случае, когда структура небольшая и легко копируется?

0 голосов
/ 11 апреля 2020

Ключ заключается в следующем: когда вы выделяете блок памяти, malloc (calloc или realloc) вернет указатель на начальный адрес в этом блоке. У вас есть 2 обязанности в отношении любого выделенного блока памяти: (1) всегда сохраняйте указатель на начальный адрес для блока памяти, поэтому (2) это может быть освобождается когда оно больше не нужно. free() должен передаваться тот же адрес, который возвращается malloc().

Нельзя предоставить адрес от середины выделенного блока до free(). Почему? Потому что это не будет адрес, первоначально возвращенный предыдущим вызовом malloc, calloc или realloc. Это требование, см. Справочную страницу для free() ( man 3 mallo c)

   The free() function frees the memory space pointed to by ptr, which must have 
   been returned by a previous call to malloc(), calloc(), or realloc().

Так что вы можете только позвонить на free() указатель, содержащий адрес, который был ранее выделен и возвращен malloc, calloc или realloc. В вашем случае это a, а не &a[1] ... &a[5].

...