【发布时间】:2019-05-17 10:24:56
【问题描述】:
我创建了一个存储整数的链表。该程序似乎运行良好,但 Valgrind 通知我存在内存泄漏。我不确定这怎么可能。下面提供了代码以及输出和 Valgrinds 评估。谢谢。
main.c
#include <stdio.h>
#include <stdlib.h>
#include "linked_list.h"
int main( int argc, char* argv[ ] ){
int num = 0;
NODE head = NULL;
num = 7;
head = list_insert( head, num );
bytes_of_list( head );
head = list_insert( head, 9 );
bytes_of_list( head );
head = list_insert( head, 2 );
bytes_of_list( head );
head = list_insert( head, 8 );
bytes_of_list( head );
delete_node( head, 6 );
delete_node( head, 9 );
bytes_of_list( head );
print_list( head );
printf( "\n" );
linked_list_destroy( &head );
bytes_of_list( head );
return 0;
}
linked_list.c
#include <stdlib.h>
#include <stdio.h>
#include "linked_list.h"
#include "status.h"
struct node;
typedef struct node Node;
struct node{
int data;
Node* next;
};
typedef struct node Node;
/************************************************************** list insert */
NODE list_insert( NODE head, int data ){
Node* pNode = NULL;
printf( "\nInsert %d into list.\n", data );
pNode = ( Node* )malloc( sizeof( Node ));
if( !pNode ) exit( 1 );
pNode->data = data;
pNode->next = head;
return pNode;
}
/****************************************************** linked_list_destroy */
void linked_list_destroy( NODE* head ){
Node* phead = ( Node* )*head;
Node* prevNode = NULL;
printf( "\nDestroy List:\n");
if( !phead ) return;
while( phead != NULL ){
prevNode = phead;
phead = phead->next;
printf( "Deleting %d\n", prevNode->data );
prevNode->data = 0;
prevNode->next = NULL;
free( prevNode );
}
*head = NULL;
}
/*************************************************************** print_list */
void print_list( NODE head ){
Node* pHead = ( Node* )head;
printf( "\nPrint list:\n");
while( pHead != NULL ){
printf( "%d ", pHead->data );
pHead = pHead->next;
}
}
/*********************************************************** delete nodes */
void delete_node( NODE head, int data ){
Node* phead = ( Node* )head;
Node* prev = NULL;
printf( "\nDelete %d from list:\n", data );
if( !head ) return;
while(( phead != NULL ) && ( phead->data != data )){
prev = phead;
phead = phead->next;
}
if( !phead ) printf( "Sorry, %d is not in the list.\n", data);
else{
prev->next = phead->next;
free( phead );
}
return;
}
/********************************************************* bytes of list */
int bytes_of_list( NODE head ){
Node* phead = ( Node* )head;
int bytes_total = 0;
while( phead != NULL ){
bytes_total += sizeof( *phead );
phead = phead->next;
}
printf( "The current size of the list is %d bytes.\n", bytes_total );
return bytes_total;
}
linked_list.h
#ifndef LINKED_LIST_H_INCLUDED
#define LINKED_LIST_H_INCLUDED
#include "status.h"
typedef void* NODE;
NODE list_insert( NODE head, int data );
void print_list( NODE head );
void linked_list_destroy( NODE* head );
void delete_node( NODE head, int data );
Status in_list( NODE head, int data );
int bytes_of_list( NODE head );
#endif
status.h
#ifndef STATUS_H_INCLUDED
#define STATUS_H_INCLUDED
enum status {FALSE, TRUE};
typedef enum status Status;
#endif
此程序的输出如下:
将 7 插入列表中。
列表的当前大小为 16 字节。
将 9 插入列表中。
列表的当前大小为 32 字节。
将 2 插入列表中。
列表的当前大小为 48 字节。
将 8 插入列表。
列表的当前大小为 64 字节。
从列表中删除 6 个:
抱歉,6 不在列表中。
从列表中删除 9:
列表的当前大小为 48 字节。
打印列表:
8 2 7
销毁清单:
删除 8
删除 2
删除 7
列表的当前大小为 0 字节。
VALGRIND 输出:
==2758== 堆摘要:
==2758== 退出时使用:1198 个块中的 140089 个字节
==2758== 总堆使用量:1,968 次分配,770 次释放,283,758 字节分配
==2758==
==2758== 泄漏摘要:
==2758== 肯定丢失:1 个块中的 10 个字节
==2758== 间接丢失:0 个块中的 0 个字节
==2758== 可能丢失:0 个块中的 0 个字节
==2758== 仍然可以访问:1197 个块中的 140079 个字节
==2758== 抑制:0 个块中的 0 个字节
==2758== 使用 --leak-check=full 重新运行以查看泄漏内存的详细信息
==2758==
==2758== 对于检测到和抑制的错误计数,重新运行:-v
==2758== 错误摘要:来自 0 个上下文的 0 个错误(已抑制:来自 0 的 0 个)
【问题讨论】:
-
我建议使用
--leak-check=full重新运行它,因为输出日志建议查看更多详细信息。 -
当我在
valgrindv3.13.0 中运行它时,我得到:All heap blocks were freed -- no leaks are possible。也许升级你的 Valgrind。 -
我试过了: valgrind -v --leak-check=full --show-leak-kinds=all make run 似乎有一个重新发生的泄漏,从 1 字节开始损失记录 1/219 并且似乎滚雪球到更大的数量,在损失记录 219/219 中以 65,536 字节结尾......我
-
我会尝试升级 Valgrind 看看会发生什么。感谢您的建议。
-
OT: about:
int main( int argc, char* argv[ ] ){当main()的参数不使用时,使用签名int main( void )
标签: c memory-leaks valgrind singly-linked-list