Strdup free 仍会导致内存泄漏

Strdup free still result in memory leaks

提问人:Jix 提问时间:11/12/2023 最后编辑:chqrlieJix 更新时间:11/12/2023 访问量:61

问:

我仍然无法弄清楚为什么这里仍然存在内存泄漏,因为(这就是错误所说的),我确保在删除节点之前释放了所有分配的内存,并在程序结束时释放了所有节点。 我错过了什么?strdupstrdup

这是我写的代码:

struct background_processes *head = NULL;

struct background_processes {
    int pid;
    char *cmd_name;
    struct background_processes *next;
};

// Add a background process to the Background processes LinkedList
void add_background_process(int pid, char *name) {
    if (head == NULL) {
        head = malloc(sizeof(struct background_processes));
        if (head == NULL) {
            exit(EXIT_FAILURE);
        }
        head->pid = pid;
        head->cmd_name = strdup(name);
        head->next = NULL;
    } else {
        struct background_processes *current = head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = malloc(sizeof(struct background_processes));
        if (current->next == NULL)
            exit(EXIT_FAILURE);
        current->next->pid = pid;
        current->next->cmd_name = strdup(name);
        current->next->next = NULL;
    }
}

// Remove a background process from the Background processes LinkedList
void remove_background_process(int pid) {
    struct background_processes *current = head;
    struct background_processes *prev = NULL;
    while (current != NULL) {
        /* If the process is running */
        if (pid == current->pid) {
            if (current == head) {
                head = head->next;
                free(current->cmd_name);
                free(current);
                current = head;
            } else {
                prev->next = current->next;
                free(current->cmd_name);
                free(current);
                current = prev->next;
            }
        } else {
            prev = current;
            current = current->next;
        }
    }
}

void free_linkedlist() {
    struct background_processes *current = head;
    struct background_processes *after;

    while (current != NULL) {
        after = current->next;
        free(current->cmd_name);
        free(current);
        current = after;
    }
}

int main() {
    // Some code 

    while (1) {
        // Some other code
        
        execute_pipeline(l);
    }
    // Freeing all allocated memory
    free_linkedlist();
}

感谢您的帮助。谢谢!

c 内存泄漏 strdup

评论

1赞 Jean-François Fabre 11/12/2023
哪个工具报告了内存泄漏?
3赞 n. m. could be an AI 11/12/2023
我们不可能测试您的代码,它不会编译。请提供一个最小的可重复示例
0赞 Ted Lyngmo 11/12/2023
如果在您发布的代码中找不到问题,则问题很可能出在 的分配中或分配中。execute_pipelinel
0赞 Jix 11/12/2023
@Jean-FrançoisFabre 它引发了编译错误:error: leak of ‘strdup(name)’ [CWE-401] [-Werror=analyzer-malloc-leak]

答:

1赞 chqrlie 11/12/2023 #1

发布的代码中没有可见的泄漏。问题一定出在别的地方:

  • 在执行未发布的代码期间,列表可能已损坏。
  • 未发布的代码可能会分配内存并泄漏内存。strdup()
  • 某些节点可能会被修改,覆盖字段。cmd_name
  • 其他一些未定义的行为可能会产生这种副作用。

建议避免重复分配和取消分配代码。

这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct background_processes {
    int pid;
    char *cmd_name;
    struct background_processes *next;
};

struct background_processes *head = NULL;

// Add a background process to the Background processes LinkedList
void add_background_process(int pid, const char *name) {
    // Allocate and initialize a new node
    struct background_processes *node = malloc(sizeof(*node));
    if (node == NULL) {
        exit(EXIT_FAILURE);
    }
    node->pid = pid;
    node->cmd_name = strdup(name);
    node->next = NULL;

    // Append the new node to the list
    if (head == NULL) {
        head = node;
    } else {
        struct background_processes *current = head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = node;
    }
}

// Remove a background process from the Background processes LinkedList
void remove_background_process(int pid) {
    struct background_processes *current = head;
    struct background_processes *prev = NULL;
    while (current != NULL) {
        struct background_processes *next = current->next;
        // If the process is running
        if (pid == current->pid) {
            // detach the node
            if (current == head) {
                head = next;
            } else {
                prev->next = next;
            }
            // deallocate the node
            free(current->cmd_name);
            free(current);
            current = next;
        } else {
            prev = current;
            current = next;
        }
    }
}

void free_linkedlist(void) {
    struct background_processes *current = head;
    while (current != NULL) {
        struct background_processes *next = current->next;
        free(current->cmd_name);
        free(current);
        current = next;
    }
}