简体   繁体   中英

C - how to get rid of memory leaks?

How can I get rid of memory leaks from for example this function:

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;
    }
}

My personal opinion is the leaks appear because of newData , temp and words variables.

I have a few similar functions that cause the same problem. I have also function for deleting Data struct, but when I call it at the end of previous function in such way DeleteData(&temp) program will not execute. I think it's because my whole list is deleted.

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;
}

How can I fix this?

Here are some problems I identified:

  • The trailing \0 in char delimiters[] = " \n\0"; is useless.

  • Testing if (IsAlphabetical(token) == 1) might be too restrictive. In C anything non 0 is true so you might test if (IsAlphabetical(token) != 0) or just if (IsAlphabetical(token)) .

  • Why allocate a copy of the string to pass to AddWords(&words, string); and then free(string) thereafter? If Addwords() does not keep the pointer it gets, there is no need to allocate a copy.

  • Does AddWords() call strtok() ? strtok() is non-reentrant, which means that if AddWords() or any other function called in this loop, such as IsAlphabetical() calls strtok() , the context used in the loop will be corrupted. You should use strtok_r() instead.

  • in function DeleteData , why do you iterate testing while (temp->pNext != NULL) ? The last item in the list does not get freed properly, the DeleteWords(&temp->words); is not called. This may cause a memory leak . You should just write:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM