c - 将字符串分配为结构成员时出现内存泄漏

标签 c string data-structures struct memory-leaks

我构建了一个函数来将节点插入到双向链表中。该结构包含 2 个字符串,我在函数内动态分配空间。根据 Valgrind 的说法,这会导致内存泄漏。这是我的代码的简化版本:

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() 内部使用 destroy 函数。这还不够吗?我是否应该以某种方式释放 add 函数内的字符串?

我在程序中重复使用此函数,因此导致大约 10.0000 字节的丢失。您能告诉我为什么会发生内存泄漏以及如何消除它吗?

最佳答案

您的add功能malloc 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");

关于c - 将字符串分配为结构成员时出现内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55420746/

相关文章:

c - 静态分配空间多大才算太大

c - 读取标记误读简单字符串 - c

c++ - 使用正弦或余弦函数在 C/C++ 中实现 3D 烟花效果

string - 判断整数是否为一位并在其前加零

c - 如何避免变量自动分配到我的指针指向的内存单元的情况?

c - 如何在 C 中同时运行两个子进程?

php - 如何替换字符串的某些部分?

vb.net - Visual Studio 不会标记 VB.Net 中未终止的字符串常量

java - 如何使用java或C#计算执行时间

c# - 对 DFS 和 BFS 程序有用的 C# 类/方法