C-如何摆脱内存泄漏?

问题描述 投票:1回答:1

如何从例如此函数中消除内存泄漏:

void AddData(Data **head, char *sentence, int number) {
    Words *words = NULL;
    char delimiters[] = " \n\0";
    char *token = strtok(sentence, delimiters);
    while (token != NULL) {
        if (IsAlphabetical(token) == 1) {
            char *string = (char *)malloc((strlen(token) + 1) * sizeof(char));
            strcpy(string, token);
            AddWords(&words, string);
            free(string);
        }
        token = strtok(NULL, delimiters);
    }

    Data *temp = *head;
    Data *newData = (Data *)malloc(sizeof(Data));

    newData->lineNumber = number;
    newData->words = words;
    newData->pNext = NULL;

    if (*head == NULL)
        *head = newData;
    else {
        while (temp->pNext != NULL)
            temp = temp->pNext;

        temp->pNext = newData;
    }
}

我个人认为是由于newDatatempwords变量而出现泄漏。

我有一些引起相同问题的相似功能。我也有删除Data结构的函数,但是当我在上一个函数的末尾以这种方式调用它时,DeleteData(&temp)程序将不会执行。我认为是因为我的整个列表已删除。

void DeleteData(Data **head) {
    Data *temp = *head;
    while (temp->pNext != NULL) {
        Data *next = temp->pNext;
        DeleteWords(&temp->words);
        free(temp);
        temp = next;
    }
    free(temp); /* to check that */
    *head = NULL;
}

我该如何解决?

c memory-leaks dynamic-memory-allocation free singly-linked-list
1个回答
0
投票

我发现了一些问题:

  • \0中的尾随char delimiters[] = " \n\0";没用。

  • 测试if (IsAlphabetical(token) == 1)可能过于严格。在C中,任何非0的值都为true,因此您可以测试if (IsAlphabetical(token) != 0)或仅测试if (IsAlphabetical(token))

  • 为什么要分配字符串的副本以传递给AddWords(&words, string);,然后再传递给free(string)?如果Addwords()不保留其获取的指针,则无需分配副本。

  • AddWords()呼叫strtok()吗? strtok()是不可重入的,这意味着如果AddWords()或此循环中调用的任何其他函数(例如IsAlphabetical()调用strtok()),则循环中使用的上下文将被破坏。您应该改用strtok_r()

  • 在功能DeleteData中,为什么要迭代测试while (temp->pNext != NULL)?列表中的最后一项没有正确释放,没有调用DeleteWords(&temp->words);这可能导致内存泄漏。您应该只写:

    void DeleteData(Data **head) {
        Data *temp = *head;
        while (temp != NULL) {
            Data *next = temp->pNext;
            DeleteWords(&temp->words);
            free(temp);
            temp = next;
        }
        *head = NULL;
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.