C语言 复制字符指针时发生内存泄漏

wfveoks0  于 2023-02-21  发布在  其他
关注(0)|答案(1)|浏览(104)

由于strsep是一个破坏性操作,我想保留line数组的内容,所以我复制了line并将其赋给变量newline。然后,我对newline执行破坏性操作。然后,我尝试释放newline,但遇到内存泄漏。我不是100%确定。但是内存泄漏很可能是由于newline没有完全释放。以前,当我对line执行破坏性的strsep操作时,我没有得到内存泄漏。我正在用fsanitize=address编译我的C代码以发现内存泄漏。

struct Item {
    char* line;
    struct Item *next;
};

struct Item* getArguments(char *line) {
  struct Item *current = NULL;
  struct Item *next = NULL;
  struct Item *first = NULL;
  char *found = NULL;
  char *newline = strdup(line);
  char blank[] = "";
  while ((found = strsep(&newline," \n")) != NULL) {
      if (strcmp(found, blank) != 0) {
        next = malloc(sizeof(struct Item));
        next->next = NULL;
        next->line = malloc((strlen(found)+1) * sizeof(char));
        strcpy(next->line, found);
        if (current) {
          current->next = next;
        }
        current = next;
        if (first == NULL) {
          first = current;
        }
      }
  }
  free(found);
  free(newline);
  newline = NULL;
  return first;
}
jum4pzuy

jum4pzuy1#

1.将参数更改为const char *line,因为您未明确修改它。
1.保留strdup(line)返回的地址的副本,以便在strsep()修改该指针时与free()一起使用。将其设置为常量指针,以真正明确地表示它。
1.不要free(found)
1.最小化变量范围。
1.条件中的赋值语句有点难读,所以我改变了循环早期返回循环的构造。

  1. if(!*found)char blank[] = "": strcmp(found, blank)相同,用于检查空字符串。
    1.检查malloc()strdup()的返回值,并在失败时处理清除。这个更改增加了许多嘈杂的错误处理。
  2. if(current)if(first == NULL实际上只是第一次迭代的一个特例,因此将它们折叠为if-else
    1.(未修复)可以将malloc()替换为calloc(),以消除行next->next = NULL
    1.(未修复)请考虑调整接口以允许调用方区分内存分配错误和未找到字符串。
#define _POSIX_C_SOURCE 200809L
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Item {
    char *line;
    struct Item *next;
};

void freeArguments(struct Item *first) {
    while (first) {
        struct Item *tmp = first->next;
        free(first->line);
        free(first);
        first = tmp;
    }
}

struct Item *getArguments(const char *line) {
    struct Item *first = NULL;
    char *const newline = strdup(line);
    if(!newline)
        goto err;
    char *newline2 = newline;
    for (struct Item *current = NULL;;) {
        char *found = strsep(&newline2," \n");
        if(!found)
            break;
        if (!*found)
            continue;
        struct Item *next = malloc(sizeof *next);
        if(!next)
            goto err;
        next->line = strdup(found);
        if(!next->line)
            goto err;
        next->next = NULL;
        if (first)
            current->next = next;
        else
            first = next;
        current = next;
    }
    free(newline);
    return first;
err:
    freeArguments(first);
    free(newline);
    return NULL;
}

int main() {
    const char *s = "hello\nworld again";
    struct Item *first = getArguments(s);
    for (struct Item *current = first; current; current = current->next)
        printf("%s\n", current->line);
    freeArguments(first);
}

瓦尔格林看起来很高兴

==1734409== HEAP SUMMARY:
==1734409==     in use at exit: 0 bytes in 0 blocks
==1734409==   total heap usage: 8 allocs, 8 frees, 1,108 bytes allocated
==1734409== 
==1734409== All heap blocks were freed -- no leaks are possible

相关问题