Как я могу узнать, успешно ли я освободил весь массив односвязных списков? - PullRequest
3 голосов
/ 05 января 2012

Я создал массив указателей. Я использовал некоторые из них в качестве корней для односвязных списков. Размер lgroup (массива указателей) равен 10, и j также может доходить до 10. Я malloc каждые lptr, как это:

lgroup[i].lptr[j] = (node *) malloc (sizeof(node));

и если я не собираюсь его использовать, я устанавливаю curr = lgroup[i].jptr[j]; и curr->next = NULL;. В противном случае я просто начинаю использовать malloc на каждом curr->next, а затем делаю curr = curr->next;. Когда я не хочу добавлять больше узлов в список, я просто помещаю curr->next = NULL; и перехожу к следующему lptr. Довольно стандартные вещи.

В конце моей программы я хочу free всю память, которую я запросил для своих списков. Вот как я пытаюсь это сделать:

for (i = 0; i < 10; i++) {
  for (j = 0; j < 10; j++) {
    if (lgroup[i].lptr[j] == NULL) {
      free(lgroup[i].lptr[j]);
      continue;
    } else {
      curr = lgroup[i].lptr[j];
      while(curr->next != NULL) {
        curr2 = curr->next;
        free(curr);
        curr = curr2;
      }
    }
  }
}

Дело в том, что я получил этот код после большого количества проб и ошибок, большого количества сообщений о «двойном освобождении» и других подобных вещах, так что я не совсем уверен, действительно ли он освобождает всю память что я утверждал или что он просто собирается и запускается без ошибок, но не выполняет все, что я хочу. Я пытался запустить его на GDB, но я действительно не могу понять многие вещи, глядя на адреса памяти, поэтому мне было любопытно, есть ли способ проверить, работает ли он, как я ожидал, или я обречен сделать это, используя ручку и бумагу и запуск кода в моей голове. Если случится так, что он действительно будет выполнять то, для чего он был разработан, будет ли более простой и чистый способ добиться тех же результатов?

Заранее спасибо, и если вам нужны какие-либо разъяснения, не стесняйтесь спрашивать об этом в комментариях.

Ответы [ 2 ]

6 голосов
/ 05 января 2012

Запустите ваш код под Valgrind .Это профилировщик памяти, который делает много вещей, но одна из вещей, которые он делает, проверяет наличие невыпущенной памяти в конце запуска приложения.

2 голосов
/ 06 января 2012

Первый вызов free в опубликованном вами коде не имеет никакого эффекта, поскольку аргумент является указателем NULL (использование continue в этом контексте также не требуется).

Также кажется, что вы не звоните бесплатно для lgroup[i].lptr[j], когда оно не равно NULL и lgroup[i].lptr[j]->next равно NULL.

Я бы переписал это:

for (i = 0; i < 10; i++) {
    for (j = 0; j < 10; j++) {
        curr = lgroup[i].lptr[j];
        while (curr != NULL) {
            curr2 = curr->next;
            free(curr);
            curr = curr2;
        }
    }
}
...