如何从例如此函数中消除内存泄漏:
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;
}
}
我个人认为是由于newData
,temp
和words
变量而出现泄漏。
我有一些引起相同问题的相似功能。我也有删除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;
}
我该如何解决?
我发现了一些问题:
\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;
}