C - 即使所有 allocs free'd 内存泄漏
C - Memory leak even with all allocs free'd
我的程序主要是获取用户输入并比较彼此的字谜。我已经在 Unix 中编译了该程序并针对它 运行 valgrind -v,但是我不明白当所有堆分配在退出时都被释放时我的内存泄漏可能来自哪里。这是我的主要方法和 valgrind 输出。
int main()
{
// Create a head node for the linked list, and a newNode variable to
//add to the list
struct node *newNode;
struct node *head = malloc(sizeof(struct node));
if(head == NULL)
{
fprintf(stderr, "Out of memory. Exiting.\n");
return 1;
}
head->next = NULL;
// For user input
char *input = NULL;
char *data;
size_t len = 0;
// Read a line in at a time
while(getline(&input, &len, stdin) != EOF)
{
// Delete newline symbol
input[strlen(input) - 1] = '[=10=]';
// Convert string to seperate words
data = strtok(input, " ");
// While there are more words from the sentence to read
while(data != NULL)
{
// Check that its a letter
int i, check = 0, length = strlen(data);
for(i = 0; i < length; i++)
{
if(isalpha(data[i]) == 0)
{
check = -1;
break;
}
}
// If a letter, create a node, set the data, and append to the
// to the linked list
if(check == 0)
{
newNode = malloc(sizeof(struct node));
if(newNode == NULL)
{
fprintf(stderr, "Out of memory. Exiting.\n");
return 1;
}
newNode->data = data;
newNode->next = NULL;
if(head->next == NULL)
{
head->next = newNode;
}
else
{
struct node *current = head;
while(current->next != NULL){
current = current->next;
}
current->next = newNode;
}
}
// If not a letter, skip the node creation and output error
else
{
fprintf(stderr, "Bad word %s\n", data);
}
data = strtok(NULL, " ");
}
input = NULL;
data = NULL;
}
print_anagrams(head->next);
// Free all mallocs and pointers
free(newNode);
free(head);
free(input);
free(data);
return 0;
}
Valgrind 输出
==32070== Invalid free() / delete / delete[] / realloc()
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F43: main (anagrams2.c:192)
==32070== Address 0x51fc1f0 is 0 bytes inside a block of size 120 free'd
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F0F: main (anagrams2.c:187)
==32070==
==32070==
==32070== HEAP SUMMARY:
==32070== in use at exit: 120 bytes in 1 blocks
==32070== total heap usage: 5 allocs, 5 frees, 288 bytes allocated
==32070==
==32070== Searching for pointers to 1 not-freed blocks
==32070== Checked 80,264 bytes
==32070==
==32070== 120 bytes in 1 blocks are definitely lost in loss record 1 of 1
==32070== at 0x4C2AB80: malloc (in /usr/lib/valgrind
/vgpreload_memcheck-amd64-linux.so)
==32070== by 0x4EA5F54: getdelim (iogetdelim.c:66)
==32070== by 0x400EF9: main (anagrams2.c:131)
==32070==
==32070== LEAK SUMMARY:
==32070== definitely lost: 120 bytes in 1 blocks
==32070== indirectly lost: 0 bytes in 0 blocks
==32070== possibly lost: 0 bytes in 0 blocks
==32070== still reachable: 0 bytes in 0 blocks
==32070== suppressed: 0 bytes in 0 blocks
==32070==
==32070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==32070==
==32070== 1 errors in context 1 of 2:
==32070== Invalid free() / delete / delete[] / realloc()
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F43: main (anagrams2.c:192)
==32070== Address 0x51fc1f0 is 0 bytes inside a block of size 120 free'd
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F0F: main (anagrams2.c:187)
==32070==
==32070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
您的代码中有 2 个问题:
- 您不应该释放
data
,因为它是从对 strtok
的调用返回的,它不是分配的指针,而只是指向 getline 返回的输入内部字符串的指针。(这主要是导致您在 Valgrind 报告中出现 Invalid Free 错误)
- 您在循环结束时将
input
设置为 NULL,因此您基本上丢失了指向 getLine
返回的内存的指针。您应该在循环内的适当位置释放 input
(这会导致您在 Valgrind 报告中出现内存泄漏错误)
我的程序主要是获取用户输入并比较彼此的字谜。我已经在 Unix 中编译了该程序并针对它 运行 valgrind -v,但是我不明白当所有堆分配在退出时都被释放时我的内存泄漏可能来自哪里。这是我的主要方法和 valgrind 输出。
int main()
{
// Create a head node for the linked list, and a newNode variable to
//add to the list
struct node *newNode;
struct node *head = malloc(sizeof(struct node));
if(head == NULL)
{
fprintf(stderr, "Out of memory. Exiting.\n");
return 1;
}
head->next = NULL;
// For user input
char *input = NULL;
char *data;
size_t len = 0;
// Read a line in at a time
while(getline(&input, &len, stdin) != EOF)
{
// Delete newline symbol
input[strlen(input) - 1] = '[=10=]';
// Convert string to seperate words
data = strtok(input, " ");
// While there are more words from the sentence to read
while(data != NULL)
{
// Check that its a letter
int i, check = 0, length = strlen(data);
for(i = 0; i < length; i++)
{
if(isalpha(data[i]) == 0)
{
check = -1;
break;
}
}
// If a letter, create a node, set the data, and append to the
// to the linked list
if(check == 0)
{
newNode = malloc(sizeof(struct node));
if(newNode == NULL)
{
fprintf(stderr, "Out of memory. Exiting.\n");
return 1;
}
newNode->data = data;
newNode->next = NULL;
if(head->next == NULL)
{
head->next = newNode;
}
else
{
struct node *current = head;
while(current->next != NULL){
current = current->next;
}
current->next = newNode;
}
}
// If not a letter, skip the node creation and output error
else
{
fprintf(stderr, "Bad word %s\n", data);
}
data = strtok(NULL, " ");
}
input = NULL;
data = NULL;
}
print_anagrams(head->next);
// Free all mallocs and pointers
free(newNode);
free(head);
free(input);
free(data);
return 0;
}
Valgrind 输出
==32070== Invalid free() / delete / delete[] / realloc()
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F43: main (anagrams2.c:192)
==32070== Address 0x51fc1f0 is 0 bytes inside a block of size 120 free'd
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F0F: main (anagrams2.c:187)
==32070==
==32070==
==32070== HEAP SUMMARY:
==32070== in use at exit: 120 bytes in 1 blocks
==32070== total heap usage: 5 allocs, 5 frees, 288 bytes allocated
==32070==
==32070== Searching for pointers to 1 not-freed blocks
==32070== Checked 80,264 bytes
==32070==
==32070== 120 bytes in 1 blocks are definitely lost in loss record 1 of 1
==32070== at 0x4C2AB80: malloc (in /usr/lib/valgrind
/vgpreload_memcheck-amd64-linux.so)
==32070== by 0x4EA5F54: getdelim (iogetdelim.c:66)
==32070== by 0x400EF9: main (anagrams2.c:131)
==32070==
==32070== LEAK SUMMARY:
==32070== definitely lost: 120 bytes in 1 blocks
==32070== indirectly lost: 0 bytes in 0 blocks
==32070== possibly lost: 0 bytes in 0 blocks
==32070== still reachable: 0 bytes in 0 blocks
==32070== suppressed: 0 bytes in 0 blocks
==32070==
==32070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==32070==
==32070== 1 errors in context 1 of 2:
==32070== Invalid free() / delete / delete[] / realloc()
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F43: main (anagrams2.c:192)
==32070== Address 0x51fc1f0 is 0 bytes inside a block of size 120 free'd
==32070== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==32070== by 0x400F0F: main (anagrams2.c:187)
==32070==
==32070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
您的代码中有 2 个问题:
- 您不应该释放
data
,因为它是从对strtok
的调用返回的,它不是分配的指针,而只是指向 getline 返回的输入内部字符串的指针。(这主要是导致您在 Valgrind 报告中出现 Invalid Free 错误) - 您在循环结束时将
input
设置为 NULL,因此您基本上丢失了指向getLine
返回的内存的指针。您应该在循环内的适当位置释放input
(这会导致您在 Valgrind 报告中出现内存泄漏错误)