C:内存泄漏实现了一个简单的链表

时间:2018-12-17 03:41:58

标签: c memory-leaks valgrind singly-linked-list

我创建了一个存储整数的链表。该程序运行正常,但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 ==在出口使用:1,198个块中的140,089字节

== 2758 ==堆总使用量:1,968个分配,770个空闲,283,758个字节分配

== 2758 ==

== 2758 ==泄漏摘要:

== 2758 ==肯定丢失:1个块中的10个字节

== 2758 ==间接丢失:0个字节,共0个块

== 2758 ==可能丢失:0字节,分为0个块

== 2758 ==仍然可以访问:1,197个块中的140,079个字节

== 2758 ==已抑制:0字节,分为0块

== 2758 ==使用--leak-check = full重新运行以查看内存泄漏的详细信息

== 2758 ==

== 2758 ==对于检测到和抑制的错误的计数,请使用-v

重新运行

== 2758 ==错误摘要:0个上下文中有0个错误(禁止:0个上下文中有0个)

1 个答案:

答案 0 :(得分:1)

这是发布代码的版本

  1. 全部卡在一个文件中
  2. 所有建议的修复程序:
  3. 干净编译的
  4. 在发生错误时通知用户

现在,该代码的建议版本:

<form action="<?php echo get_site_url() ?>" method="GET">
    <div class="input-group">
        <input type="search" name="s" class="form-control" placeholder="Search Products" required>
        <input type="hidden" name="post_type" value="products" />
        <div class="input-group-btn">
            <button class="btn btn-default" type="submit">
                 <i class="fa fa-search" aria-hidden="true"></i>
            </button>
        </div>
    </div>
</form>