Основной Malloc / Free - PullRequest
       12

Основной Malloc / Free

3 голосов
/ 30 октября 2011

Если у меня есть фрагмент моей программы, подобный этому:

struct Node *node;
while(...){
    node = malloc(100);
    //do stuff with node
}

Это означает, что каждый раз, когда я зацикливаюсь в цикле while, я заново выделяю 100 байтов, на которые указывает указатель узла, верно?

Если это так, то как мне освободить всю память, которую я создал, со всеми циклами, если у меня есть только указатель влево, указывающий на последний произошедший malloc?

Спасибо!

Ответы [ 5 ]

4 голосов
/ 30 октября 2011

Пожалуйста, выделите именно тот размер, который вам нужен: malloc(sizeof *node); - если вы перейдете на 64-битную платформу, которая удваивает размер всех ваших членов, ваша старая 96-байтовая структура может занять 192 байта в новой среде.

Если у вас нет указателей ни на одну из struct Node, которые вы создали, то я не думаю, что вам следует назначать их с malloc(3) в первую очередь. malloc(3) лучше всего, если ваше приложение требует, чтобы данные сохранялись вне области вызова текущей функции. Я ожидаю , что вы могли бы переписать свою функцию следующим образом:

struct Node node;
while(...){
    //do stuff with node
}

или

while(...){
    struct Node node;
    //do stuff with node
}

в зависимости от того, хотите ли вы получить доступ к последнему узлу (первая версия) или нет (вторая версия).

Конечно, если вам действительно нужны эти структуры вне этого фрагмента кода, тогда вам нужно хранить ссылки на них где-то . Добавьте их в глобальный список, отслеживающий struct Node объектов, или добавьте каждый из них к указателю next предыдущего struct Node, или добавьте каждый к соответствующему struct User, который относится к их, что лучше для вашего приложения.

1 голос
/ 30 октября 2011

Если вам больше не нужно пространство, выделенное malloc, в конце одной итерации, вы должны сразу освободить его.

Чтобы отслеживать выделенные узлы, вы можете сохранить их в динамически растущемlist:

#include <stdlib.h>

int main() {
    int i;
    void *node;
    int prt_len = 0;
    void **ptrs = NULL;
    for (i = 0; i < 10; i++) {
        node = malloc(100);
        ptrs = realloc(ptrs, sizeof(void*) * ++prt_len);
        ptrs[prt_len-1] = node;
        /* code */
    }
    for (i = 0; i < prt_len; i++) {
        free(ptrs[i]);
    }
    free(ptrs);
    return 0;
}

Примечание. Вероятно, вам следует переосмыслить свой алгоритм, если вам необходимо использовать такие методы!

В противном случае см. ответ Сарнольда .

1 голос
/ 30 октября 2011

Если вы установите node = NULL перед циклом, а затем используете free (node) перед node = malloc (100), все будет в порядке.Вам также нужно будет выполнить освобождение (узел) после выхода из цикла.Но опять же, все зависит от того, что на самом деле делает "// делать вещи с узлом".Как уже отмечали другие, malloc (100) не очень хорошая идея.Я бы использовал malloc (sizeof (* node)).Таким образом, если тип узла меняется, вам не нужно менять строку malloc.

0 голосов
/ 30 октября 2011

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

0 голосов
/ 30 октября 2011

тогда как мне освободить всю память, которую я создал, со всеми циклами, если у меня есть только указатель влево, указывающий на последний произошедший malloc?

Ты не можешь. Вы только что создали гигантскую утечку памяти .

Вы должны отслеживать каждый кусок памяти, который вы malloc() и free(), когда закончите с его использованием.

...