C-内存泄漏,即使所有allocs可用
我的程序基本上得到用户的输入,并比较每个单词的字谜。我已经在Unix中编译了这个程序,并针对它运行了valgrind-v,但是我不知道当所有堆分配在退出时都被释放时,内存泄漏会从何而来。这是我的主要方法和valgrind输出C-内存泄漏,即使所有allocs可用,c,memory-leaks,getline,C,Memory Leaks,Getline,我的程序基本上得到用户的输入,并比较每个单词的字谜。我已经在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 *newNod
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] = '\0';
// 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;
}
您的代码中有两个问题: 您不应该释放数据,因为它是从调用strtok返回的,不是malloced指针,只是getline返回的输入中字符串的指针。这通常会导致Valgrind报告中出现无效的释放错误 在循环结束时将input设置为NULL,因此基本上丢失了getLine返回的内存指针。您应该在适当的位置释放循环内的输入,这会导致Valgrind报告中的内存泄漏错误
数据不是一个指向输入中的字符串的指针,该字符串由getline进行malloc'ed。释放它的问题在于它可能不指向getline分配的块的开头。一个很好的提示是,在一个大小为120的块中,getLine中的默认分配大小如果他恰好有来自strtok的第一个令牌的数据点,那么他实际上是在释放输入,在将数据复制并存储到单独的内存块中之后,他无论如何都应该这样做。使用getline的大规则,您不能丢失对输入分配开始的引用,也不能丢失释放getline分配的块的能力。分配新的块来存储输入的一部分总是更好的,这样输入就可以留在getline中供其在后续读取时重用。最好是将malloced缓冲区作为输入发送到getline。如果需要,它可以调整大小。继续为多个调用发送相同的输入指针,并在退出循环后释放它。这也清楚地确定了谁是代码读取器的内存所有者。如果您释放行,则链表中存储的所有数据指针都将被挂起。如果您使用getline,并且在出口处看到正在使用:1个块中有120个字节,然后,这将提示您,在您的案例中,您无法释放或误用由getline input分配的缓冲区。getline缓冲区的默认分配大小为120字节。
==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)