Утечка памяти при выделении строк в качестве членов структуры - PullRequest
0 голосов
/ 29 марта 2019

Я построил функцию для вставки узла в двусвязный список.Структура включает в себя 2 строки, для которых я динамически распределяю пространство внутри функции.По словам Вальгринда, это вызывает утечку памяти.Вот упрощенная версия моего кода:

typedef struct Node {
    char *str1, *str2;
    Node *next, *prev;
};

void add(Node* list, char* string1, char* string2) {         
   Node* temp = list;
   Node* new_node = (Node*) malloc(sizeof(Node));
   if (!new_node) return;

   new_node->str1 = (char*) malloc(30*sizeof(char));
   new_node->str2 = (char*) malloc(30*sizeof(char));
   strcpy(new_player->str1, string1);
   strcpy(new_player->str2, string2);

   if (!temp) {
      temp = new_node;
      new_node->prev = new_node->next = NULL;
      new_node = NULL;
      free(new_node);
      return;
   } else {
       while (temp->next) temp = temp->next;

       new_node->prev = temp;
       new_node->next = NULL;
       temp->next =new_node;

       new_node = NULL;
       free(new_node);
   }

   void destroy(Node* list) {
      Node* temp;
      while (list) {
         temp = list->next;
         free(list->str1); 
         free(list->str2);
         free(list); 
         list = temp;
      }  
  }

Я использую функцию уничтожения внутри main () после окончания работы со списком.Это не достаточно?Я должен как-то освободить строки внутри функции добавления?

Я неоднократно использую эту функцию в своей программе, поэтому она вызывает потерю около 10,0000 байт.Подскажите, пожалуйста, почему происходит утечка памяти и как от нее избавиться?

1 Ответ

0 голосов
/ 29 марта 2019

Ваша add функция malloc sa Node связывает ее со списком, а затем free s выделяет Node по некоторым причинам.Это оставит в списке висячие указатели.

Ваша функция add также не имеет механизма добавления первого Node в пустой список.Есть два способа сделать это.Первый способ - вернуть указатель на первый узел списка:

Node* add(Node* list, char* string1, char* string2) {         
    Node* temp = list;
    Node* new_node = malloc(sizeof(Node));
    if (!new_node) return NULL;

    new_node->str1 = malloc(strlen(string1)+1);
    new_node->str2 = malloc(strlen(string2)+1);
    if (!new_node->str1 || !new_node->str2) {
        // allocation error for one of the strings
        free(new_node->str1);
        free(new_node->str2);
        free(new_node);
        return NULL;
    }

    strcpy(new_node->str1, string1);
    strcpy(new_node->str2, string2);
    new_node->next = NULL;

    if (!temp) {
        new_node->prev = NULL;
        list = new_node;
    } else {
        while (temp->next) temp = temp->next;

        new_node->prev = temp;
        temp->next = new_node;
    }

    // return pointer to first node
    return list;
}

Пример вызова с использованием первого способа:

Node* mylist = NULL;
...
mylist = add(mylist, "hello", "world");

Второй способ - изменить первый параметр.на указатель на указатель на начало списка:

void add(Node** list, char* string1, char* string2) {         
    Node* temp = *list;
    Node* new_node = malloc(sizeof(Node));
    if (!new_node) return;

    new_node->str1 = malloc(strlen(string1)+1);
    new_node->str2 = malloc(strlen(string2)+1);
    if (!new_node->str1 || !new_node->str2) {
        // allocation error for one of the strings
        free(new_node->str1);
        free(new_node->str2);
        free(new_node);
        return;
    }

    strcpy(new_node->str1, string1);
    strcpy(new_node->str2, string2);
    new_node->next = NULL;

    if (!temp) {
        new_node->prev = NULL;
        *list = new_node;
    } else {
        while (temp->next) temp = temp->next;

        new_node->prev = temp;
        temp->next = new_node;
    }
}

Пример вызова с использованием второго способа:

Node* mylist = NULL;
...
add(&mylist, "hello", "world");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...