Как мне освободить весь массив, элементы которого были отдельно выделены памяти с помощью вызовов malloc / calloc [дубликат]

Aug 16 2020

Насколько я знаю, malloc и calloc - это просто API-интерфейсы для учета в базовой памяти. Имея это в виду, мне интересно, освободит ли вызов free () весь массив, отдельные элементы которого были выделены памятью посредством независимых вызовов malloc (или calloc).

Точнее, у меня такой код:

int *num,* num_start;

num_start=num;

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

free(num_start);

Освободит ли free(num_start)весь массив из N целочисленных элементов, которым было динамически выделено пространство, независимо?

Ответы

1 P__JsupportswomeninPoland Aug 16 2020 at 10:09

Опубликованный вами "код" не имеет смысла и неверен.

int *num, num_start;
num_start=num;

num_start - целое число, а не указатель.

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

честно говоря, я не понимаю, что должен делать этот код, но точно не так

если вы хотите выделить память для Nцелых чисел

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

и для освобождения тебе нужно только

free(num);

Или, если вы хотите выделить указатель для хранения N указателей на N целых чисел

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);
}

Когда вы выделяете память, вы должны проверить, была ли операция успешной. Эти проверки не включены в пример, чтобы код было легче читать.

tadman Aug 16 2020 at 09:55

Функции calloc()и malloc()возвращают указатель на выделение, которое служит дескриптором для освобождения этой памяти. Хотя вы можете делать копии этого указателя и манипулировать ими по своему усмотрению, при вызове free()вы должны указать исходное значение .

То есть это работает:

// 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);

Вы также можете немного попробовать себя в приключениях, если вернетесь в исходное место назначения:

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

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

free(x);

Где здесь xвернулся к первоначальной стоимости после короткого путешествия. В общем случае лучше сохранить исходный указатель, чем восстанавливать его позже. Сделайте копии, если вы собираетесь ими манипулировать.