C: утечка памяти, реализующая простой связанный список - PullRequest
0 голосов
/ 17 декабря 2018

Я создал связанный список, в котором хранятся целые числа.Программа работает нормально, но 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;
}

connected_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;
}

connected_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 == HEРЕЗЮМЕ AP:

== 2758 == используется на выходе: 140 089 байт в 1198 блоках

== 2758 == общее использование кучи: 1 968 выделений, 770 освобождений, 283 758 выделенных байтов

== 2758 ==

== 2758 == РЕЗЮМЕ УТЕЧКИ:

== 2758 == определенно потеряно: 10 байтов в 1 блоках

==2758 == косвенно потеряно: 0 байтов в 0 блоках

== 2758 == возможно потеряно: 0 байтов в 0 блоках

== 2758 == все еще достижимо: 140 079 байтов в 1 197 блоках

== 2758 == подавлено: 0 байт в 0 блоках

== 2758 == Перезапустите с --leak-check = full, чтобы увидеть детали утечки памяти

== 2758 ==

== 2758 == Для подсчета обнаруженных и подавленных ошибок повторно запустите: -v

== 2758 == РЕЗЮМЕ ОШИБОК: 0 ошибок из 0 контекстов (исключено:0 из 0)

1 Ответ

0 голосов
/ 17 декабря 2018

Вот версия отправленного кода

  1. , все в одном файле
  2. со всеми предлагаемыми исправлениями:
  3. , который аккуратно компилируется
  4. , который информирует пользователя при возникновении ошибки

А теперь предложенная версия кода:

#ifndef STATUS_H_INCLUDED
#define STATUS_H_INCLUDED
enum status {FALSE, TRUE};
typedef enum status Status;
#endif



#ifndef LINKED_LIST_H_INCLUDED
#define LINKED_LIST_H_INCLUDED
//include "status.h"
#include <stdio.h>

struct node 
{ 
    int data; 
    struct node *next; 
}; 
typedef struct node 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 );
void bytes_of_list( Node* head );

#endif


#include <stdio.h>
#include <stdlib.h>
//#include "linked_list.h"

int main( void )
{
    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;
}


//#include <stdlib.h>
//#include <stdio.h>
//#include "linked_list.h"
//#include "status.h"




/************************************************************** list insert */
Node *list_insert( Node *head, int data )
{
    printf( "\nInsert %d into list.\n", data );

    Node *pNode = malloc( sizeof( Node ));
    if( !pNode )
    {
        perror( "malloc failed" );
        exit( 1 );
    }

    pNode->data = data;
    pNode->next = head;
    return pNode;
}


/******************************************************  linked_list_destroy */
void linked_list_destroy( Node** head )
{
    Node* phead = *head;
    Node* prevNode = NULL;

    printf( "\nDestroy List:\n");


    while( phead )
    {
        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 = head;

    printf( "\nPrint list:\n");

    while( pHead )
    {
        printf( "%d ", pHead->data );
        pHead = pHead->next;
    }
}


/***********************************************************  delete nodes */
void delete_node( Node **head, int data )
{
    Node* phead = *head;
    Node* prev  = NULL;

    printf( "\nDelete %d from list:\n", data );

    //if( !head ) return;

    while(( phead ) && ( 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 */
void bytes_of_list( Node* head )
{
    Node* phead = head;
    size_t bytes_total = 0;

    while( phead )
    {
        bytes_total += sizeof( *phead );
        phead = phead->next;
    }

    printf( "The current size of the list is %lu bytes.\n", bytes_total );
    //return bytes_total;
}
...