用C链表内存泄漏 [英] Memory Leaks in C Linked List

查看:227
本文介绍了用C链表内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直工作在学校的一个项目(由于今晚!),和我有一些严重的内存问题。我是相当新的C和我仍然被抛出了一个循环,当谈到mallocing指针和诸如此类的东西,所以我真的可以使用一些帮助。

在code如下。该文件的顺序是LinkedLists.h(标题为链表模块),LinkedLists.c(链表模块),和TestList.c(主模块)。

  / ********* *****************************************
*基础结构包含数据结构元素信息:由deterimined
*应用程序需要。
************************************************** ************ /
的#ifndef _LINKED_LISTS_H_
#定义_LINKED_LISTS_H_typedef结构ElementStructs
  {
        INT ElementPosition;
        字符* ElementValue;
  } ElementStructs;/ **************没有别的模块中需要修改************* // ******************* *****************************
*列表中的节点的结构基础,包含用户信息和链​​接指针。
*该ElementStructstypemark必须定义根据的具体需要
*应用程序。
************************************************** ************ /
typedef结构LinkedListNodes
  {
   / *用户信息字段* /
   ElementStructs * ElementPtr;
   / *链接指针* /
   结构LinkedListNodes *下一步;
   结构LinkedListNodes * previous;
  } LinkedListNodes;/ ******************* *****************************
*基础结构用于管理链表数据结构。
************************************************** ************ /
typedef结构LinkedLists
  {
   / *列表中的元素数* /
   INT numElements个;
   / *指向元素列表的前面,可能为NULL * /
   结构LinkedListNodes * FrontPtr;
   / *指向元素列表的末尾,可能为NULL * /
   结构LinkedListNodes * BackPtr;
  } LinkedLists;/ ******************* *****************************
*初始化链表数据结构
************************************************** ************ /
无效InitLinkedList(LinkedLists * ListPtr);/ ******************* *****************************
*将记录添加到列表的前面。
************************************************** ************ /
无效AddToFrontOfLinkedList(LinkedLists * ListPtr,ElementStructs * DataPtr);/ ******************* *****************************
*将记录添加到列表的后面。
************************************************** ************ /
无效AddToBackOfLinkedList(LinkedLists * ListPtr,ElementStructs * DataPtr);/ ******************* *****************************
*删除(返回)从列表中的前一个记录(作品甚至在
*通过返回NULL一个空列表)。
************************************************** ************ /
ElementStructs * RemoveFromFrontOfLinkedList(LinkedLists * ListPtr);/ ******************* *****************************
*移除(和返回)从列表的背面的记录(作品,即使上
*通过返回NULL一个空列表)。
************************************************** ************ /
ElementStructs * RemoveFromBackOfLinkedList(LinkedLists * ListPtr);/ ******************* *****************************
*德分配链表并复位结构字段仿佛
*列表是空的。
************************************************** ************ /
无效DestroyLinkedList(LinkedLists * ListPtr);#ENDIF / * * _LINKED_LISTS_H_ /

LinkedLists.c:

  / ********* *****************************************
*提取并打印从指定数据的第一个和最后6个元素
*设置并打印在输入文件中的单词的总数。利用
在LinkedLists.h指定* LinkedList的模块
*通过书面XXXXXXX
************************************************** ************ /
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LinkedLists.h无效InitLinkedList(LinkedLists * ListPtr)
{
        ListPtr-> numElements个= 0;
        ListPtr-> FrontPtr = NULL;
        ListPtr-> BackPtr = NULL;
}无效AddToFrontOfLinkedList(LinkedLists * ListPtr,ElementStructs
        * DataPtr)
{        / *如果没有其他元素,创造新的节点,并添加它,
         *将其分配给这两个前和后的指针* /
        如果(ListPtr-> numElements个== 0)
        {
                ListPtr-> FrontPtr =的malloc(sizeof的(LinkedListNodes));
                ListPtr-> FrontPtr-> ElementPtr = DataPtr;
                ListPtr-> FrontPtr->接着= NULL;
                ListPtr-> FrontPtr-> previous = NULL;
                ListPtr-> BackPtr = ListPtr-> FrontPtr;
        }        / *如果有其他的元素,创建新节点并把它添加到前
         *同时保留previous节点顺序* /
        其他
        {
                / *初始化新的一个LinkedListNode * /
                ListPtr-> FrontPtr-> previous =的malloc(sizeof的(LinkedListNodes));
                ListPtr-> FrontPtr-> previous-> ElementPtr = DataPtr;
                ListPtr-> FrontPtr-> previous->接下来= ListPtr-> FrontPtr;
                ListPtr-> FrontPtr-> previous-> previous = NULL;                / *指定新初始化的节点作为链表的前面节点* /
                ListPtr-> FrontPtr = ListPtr-> FrontPtr-> previous;
        }        / *列表大小加1 *​​ /
        (ListPtr-> numElements个)++;
}无效AddToBackOfLinkedList(LinkedLists * ListPtr,ElementStructs
        * DataPtr)
{
        / *如果没有其他元素,创造新的节点,并添加它,
         *将其分配给这两个前和后的指针* /
        如果(ListPtr-> numElements个== 0)
        {
                ListPtr-> FrontPtr =的malloc(sizeof的(LinkedListNodes));
                ListPtr-> FrontPtr-> ElementPtr = DataPtr;
                ListPtr-> FrontPtr->接着= NULL;
                ListPtr-> FrontPtr-> previous = NULL;
                ListPtr-> BackPtr = ListPtr-> FrontPtr;
                / *的printf(添加%s \\ n,DataPtr-> ElementValue); * /
        }        / *如果有其他的元素,创建新节点并把它添加到后面
         *同时保留previous节点顺序* /
        其他
        {
                / *初始化新的一个LinkedListNode * /
                ListPtr-> BackPtr->接着= malloc的(的sizeof(LinkedListNodes));
                ListPtr-> BackPtr->下一步 - > ElementPtr = DataPtr;
                ListPtr-> BackPtr->下一步 - > previous = ListPtr-> BackPtr;
                ListPtr-> BackPtr->下一步 - > previous = ListPtr-> BackPtr;
                ListPtr-> BackPtr->下一步 - >接着= NULL;                / *指定新初始化节点的LinkedList的背面节点* /
                ListPtr-> BackPtr = ListPtr-> BackPtr->接下来,
                的printf(添加%s \\ n,ListPtr-> BackPtr-> ElementPtr-> ElementValue);
        }        / *列表大小加1 *​​ /
        (ListPtr-> numElements个)++;
}ElementStructs * RemoveFromFrontOfLinkedList(LinkedLists * ListPtr)
{
        如果(ListPtr-> numElements个大于0)
        {
                ElementStructs * removedElement = ListPtr-> FrontPtr-> ElementPtr;
                LinkedListNodes * removedNode = ListPtr-> FrontPtr;
                 如果(ListPtr-> numElements个== 1)
            {
                    ListPtr-> FrontPtr = NULL;
            }
            其他
            {
                    ListPtr-> FrontPtr = ListPtr-> FrontPtr->接下来,
                    ListPtr-> FrontPtr-> previous = NULL;
            }
            (ListPtr-> numElements个) - ;
            免费(removedNode);
            返回removedElement;
    }
    其他
    {
            ElementStructs * nullElement = NULL;
            返回nullElement;
    }
}ElementStructs * RemoveFromBackOfLinkedList(LinkedLists * ListPtr)
{
        如果(ListPtr-> numElements个→1)
        {
                ElementStructs * removedElement = ListPtr-> BackPtr-> ElementPtr;
                LinkedListNodes * removedNode = ListPtr-> BackPtr;
                如果(ListPtr-> numElements个== 1)
                {
                        ListPtr-> BackPtr = NULL;
                }
                其他
                {
                        ListPtr-> BackPtr = ListPtr-> BackPtr-> previous;
                        ListPtr-> BackPtr->接着= NULL;
                }
                (ListPtr-> numElements个) - ;
                免费(removedNode);
                返回removedElement;
        }
        其他
        {
                ElementStructs * nullElement = NULL;
                返回nullElement;
        }
}
无效DestroyLinkedList(LinkedLists * ListPtr)
{
        而(ListPtr->!FrontPtr = NULL)
        {
                LinkedListNodes * removedNode = ListPtr-> FrontPtr;
                ListPtr-> FrontPtr = ListPtr-> FrontPtr->接下来,                / *在节点取消分配单元* /
                免费(removedNode-> ElementPtr-> ElementValue);
                免费(removedNode-> ElementPtr);                / *解除分配节点* /
                免费(removedNode);
        }
        免费(ListPtr);
}

TestList.c:

  / ********* *****************************************
 *测试用LinkedLists.h指定的链表的功能
 *文件美式英语的话。读取单个单词,并将它们存储
 *如在LinkedList的节点元素。
 *通过书面XXXXX
 ************************************************** *************************** /
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LinkedLists.hMAX_LENGTH的#define 100 / *中的任何专业英语词典*最长的单词长度/INT主(INT ARGC,字符**参数)
{
        如果(的argc == 2)
        {
                / *初始化链表* /
                LinkedLists * LL;                / *文件指针输入文件* /
                FILE * FP;                / *节点从文件存储*输入数据/
                ElementStructs * NODEDATA;                / *循环完成布尔* /
                诠释完成;                / *循环位置计数器* /
                INT位置;                / * *迭代器/
                ElementStructs * CurElement;                / *打开输入文件,并检查它是可读的。如果不是,退出* /
                FP = FOPEN(参数[1],R);                如果(FP == NULL)
                {
                        fprintf中(标准错误,文件打开失败。);
                        返回2;
                }                / *初始化链表和其它必要的变量* /
                LL =的malloc(sizeof的(* LL));
                InitLinkedList(LL);                完成= 0;
                位置= 0;                做
                {
                        如果(!的feof(FP))
                        {
                                / *分配空间的新节点的数据* /
                                NODEDATA =的malloc(sizeof的(ElementStructs));                                / *分配的节点元素的空间输入字符串* /
                                NodeData-> ElementValue =的malloc(MAX_LENGTH *的sizeof(字符));                                从文件* / *读取新节点的数据/
                                的fscanf(FP,%S,NodeData-> ElementValue);                                / *指定扫描值节点单元* /
                                NodeData-> ElementPosition =位置;
                                / *的strcpy(NodeData-> ElementValue,readString); * /                                / *数据节点添加到链表* /
                                AddToFrontOfLinkedList(LL,NODEDATA);
                        }
                        其他
                                DONE = 1;
                        位置++;
                }而(完成== 0);                做
                {
                        CurElement = RemoveFromFrontOfLinkedList(LL);                        如果(CurElement!= NULL)
                                的printf(字#%D:%S \\ n,CurElement-> ElementPosition,
                                CurElement-> ElementValue);
                }而(CurElement!= NULL);                / *解除分配链表* /
                DestroyLinkedList(LL);
                FCLOSE(FP);        }
        / *错误的命令行输入* /
        其他
        {
                fprintf中(标准错误,不正确数量的参数);
                返回1;
        }        返回0;
}

程序编译罚款。但是,运行它会导致在执行的最后一个赛格故障,并报告Valgrind的多个内存泄漏(如下图所示)。请,如果您有任何帮助提供,我将非常感谢。这个问题主要是在LinkedList.c模块中的RemoveFromBackOfLinkedList和RemoveFromFrontOfLinkedList方法。有code的主模块(TestList.c)调用这些函数在块(我都试过,但它们有几乎相同的功能,也不工作)。块是做/同时显示如下循环:

 
                {
                CurElement = RemoveFromFrontOfLinkedList(LL);                        如果(CurElement!= NULL)
                                的printf(字#%D:%S \\ n,CurElement-> ElementPosition,
                                CurElement-> ElementValue);
                }而(CurElement!= NULL);

Valgrind的结果:

 字#225921:化学计量




字#6:凸轮
字#5:石化的
字#4:万亿
字#3:祝福
字#2:wisted
字#1:毒素
== == 4849尺寸为8的写入无效
== == 4849在0x400B5C:RemoveFromFrontOfLinkedList(在/ home / amb2189 / HW3 / TestList)
== == 4849通过0x40085B:主(在/ home / amb2189 / HW3 / TestList)
== == 4849地址为0x10不stack'd,malloc分配或(最近)free'd
== == 4849
== == 4849
== == 4849过程终止与信号11的默认操作(SIGSEGV)
== == 4849地址为0x10不映射区域内访问
== == 4849在0x400B5C:RemoveFromFrontOfLinkedList(在/ home / amb2189 / HW3 / TestList)
== == 4849通过0x40085B:主(在/ home / amb2189 / HW3 / TestList)
== == 4849如果你认为发生这种情况作为一个堆栈的结果
== == 4849溢出程序的主线程(不可能的,但
== == 4849可能),你可以尝试增加的大小
== == 4849用 - 主 - STACKSIZE =标志主线程堆栈。
== == 4849在这个运行中所用的主线程的堆栈大小是8388608。
== == 4849
== == 4849 HEAP摘要:
== == 4849使用在出口处:在413185块23965172字节
== == 4849总堆的使用情况:619775 allocs,206590的FreeS,28923332字节分配
== == 4849
== == 4849在16块1个字节可能迷失在负的战绩1 9
== == 4849在0x4C2B6CD:的malloc(以/usr/lib/valgrind/vg$p$pload_memcheck-amd64-linux.so)
== == 4849通过0x4007E2:主(在/ home / amb2189 / HW3 / TestList)
== == 4849
== == 4849 200 2块字节可能迷失在负的战绩5 9
== == 4849在0x4C2B6CD:的malloc(以/usr/lib/valgrind/vg$p$pload_memcheck-amd64-linux.so)
== == 4849通过0x4007F0:主(在/ home / amb2189 / HW3 / TestList)
== == 4849
== == 4849 23963992(3305392直接,间接20658600)字节206587块9的9负的战绩肯定是丢
== == 4849在0x4C2B6CD:的malloc(以/usr/lib/valgrind/vg$p$pload_memcheck-amd64-linux.so)
== == 4849通过0x4007E2:主(在/ home / amb2189 / HW3 / TestList)
== == 4849
== == 4849泄漏摘要:
== == 4849肯定丢失:3305392字节206587块
== == 4849失去了间接的:20658600字节206586块
== == 4849可能丢失:216字节的3个街区
== == 4849到达尚:在9块964字节
== == 4849燮pressed:0字节0块
== 4849 ==可达块(那些其中指针被发现)未示出。
== == 4849要查看它们,重新运行:--leak检查=全--show-可达= YES
== == 4849
== == 4849对于检测燮pressed错误计数,重新运行:-v
== == 4849使用--track-起源= yes来看到未初始化值来自
== == 4849错误摘要:从5环境5个错误(SUP pressed:2 2)
分段错误(核心转储)


解决方案

请一些变化在2删除等功能,,

  ElementStructs * RemoveFromFrontOfLinkedList(LinkedLists * ListPtr)
{
        如果(ListPtr-> numElements个大于0)
        {
        / * * ElementStructs = removedElement&ListPtr- GT; FrontPtr-> ElementPtr; * /
                / * * LinkedListNodes = removedNode的malloc(sizeof的(removedNode)); //无需进行分配,因为要删除的节点
                removedNode = ListPtr-> FrontPtr; * /
                LinkedListNodes * removedNode = ListPtr-> FrontPtr; //使用这行
                ListPtr-> FrontPtr = ListPtr-> FrontPtr->接下来,
                ListPtr-> FrontPtr-> previous = NULL;
                免费(removedNode);
                (ListPtr-> numElements个) - ;
                返回NULL;
        }
        其他
        {
                ElementStructs * nullElement = NULL;
                返回nullElement;
        }
}ElementStructs * RemoveFromBackOfLinkedList(LinkedLists * ListPtr)
{
        如果(ListPtr->!numElements个= 0)
        {
                ElementStructs * removedElement = ListPtr-> BackPtr-> ElementPtr;
                LinkedListNodes * removedNode = ListPtr-> BackPtr;
                ListPtr-> BackPtr = ListPtr-> BackPtr-> previous;
                ListPtr-> BackPtr->接着= NULL;
                免费(removedNode);
                (ListPtr-> numElements个) - ; //添加此行
                返回removedElement;
        }
        其他
        {
                ElementStructs * nullElement = NULL;
                返回nullElement;
        }
}

修改1

CurElement =的malloc(sizeof的(* CurElement)); 这是另一个MEM-泄漏,你不必使用malloc它,只是删除此行。

编辑2:你为什么不释放你的元素和ELEMENTVALUE ...

 
{
        CurElement = RemoveFromFrontOfLinkedList(LL);        如果(CurElement!= NULL){
                的printf(字#%D:%S \\ n,CurElement-> ElementPosition,
                CurElement-> ElementValue);
                免费(CurElement-> ElementValue); //添加这些2号线释放ELEMENTVALUE和元素。
                免费(CurElement);
        }
}而(CurElement!= NULL);

I've been working on a project for school (Due tonight!), and I'm having some serious memory issues. I'm fairly new to C and am still being thrown for a loop when it comes to mallocing pointers and whatnot, so I could really use some help.

The code is as follows. The order of the files is LinkedLists.h (Header for LinkedList module), LinkedLists.c (LinkedList module), and TestList.c (Main module).

/******************************************************************************
* Base struct to contain data structure element information: deterimined by
* the application needs.
******************************************************************************/
#ifndef _LINKED_LISTS_H_
#define _LINKED_LISTS_H_

typedef struct ElementStructs
  {
        int ElementPosition;
        char* ElementValue;
  } ElementStructs;

/**************  Nothing else in the module needs to be modified *************/



/******************************************************************************
* Base struct of list nodes, contains user information and link pointers.
* The "ElementStructs" typemark must be defined based on specific needs of the
* application.
******************************************************************************/
typedef struct LinkedListNodes
  {
   /* The user information field */
   ElementStructs *ElementPtr;
   /* Link pointers */
   struct LinkedListNodes *Next;
   struct LinkedListNodes *Previous;
  } LinkedListNodes;

/******************************************************************************
* Base struct used to manage the linked list data structure.
******************************************************************************/
typedef struct LinkedLists
  {
   /* Number of elements in the list */
   int NumElements;
   /* Pointer to the front of the list of elements, possibly NULL */
   struct LinkedListNodes *FrontPtr;
   /* Pointer to the end of the list of elements, possibly NULL */
   struct LinkedListNodes *BackPtr;
  } LinkedLists;

/******************************************************************************
* Initialized the linked list data structure
******************************************************************************/
void InitLinkedList(LinkedLists *ListPtr);

/******************************************************************************
* Adds a record to the front of the list.
******************************************************************************/
void AddToFrontOfLinkedList(LinkedLists *ListPtr, ElementStructs *DataPtr);

/******************************************************************************
* Adds a record to the back of the list.
******************************************************************************/
void AddToBackOfLinkedList(LinkedLists *ListPtr, ElementStructs *DataPtr);

/******************************************************************************
* Removes (and returns) a record from the front of the list ('works' even on 
* an empty list by returning NULL).
******************************************************************************/
ElementStructs *RemoveFromFrontOfLinkedList(LinkedLists *ListPtr);

/******************************************************************************
* Removes (and returns) a record from the back of the list ('works' even on 
* an empty list by returning NULL).
******************************************************************************/
ElementStructs *RemoveFromBackOfLinkedList(LinkedLists *ListPtr);

/******************************************************************************
* De-allocates the linked list and resets the struct fields as if the
* list was empty.
******************************************************************************/
void DestroyLinkedList(LinkedLists *ListPtr);

#endif /* _LINKED_LISTS_H_ */

LinkedLists.c:

/******************************************************************************
* Extracts and prints the first and last 6 elements from the specified data 
* set and prints the total number of words in the input file. Utilizes the
* LinkedList module as specified in LinkedLists.h
* Written by xxxxxxx
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "LinkedLists.h"

void InitLinkedList(LinkedLists *ListPtr)
{
        ListPtr->NumElements = 0;
        ListPtr->FrontPtr = NULL;
        ListPtr->BackPtr = NULL;
}

void AddToFrontOfLinkedList(LinkedLists *ListPtr, ElementStructs
        *DataPtr)
{

        /* If there are no other elements, create new node and add it,
         * assigning it to both the front and back pointers */
        if(ListPtr->NumElements == 0)
        {
                ListPtr->FrontPtr = malloc(sizeof(LinkedListNodes));
                ListPtr->FrontPtr->ElementPtr = DataPtr;
                ListPtr->FrontPtr->Next = NULL;
                ListPtr->FrontPtr->Previous = NULL;
                ListPtr->BackPtr = ListPtr->FrontPtr;
        }

        /* If there are other elements, create new node and add it to the front
         * while retaining previous node order */
        else
        {
                /* Initialize new LinkedListNode */
                ListPtr->FrontPtr->Previous = malloc(sizeof(LinkedListNodes));
                ListPtr->FrontPtr->Previous->ElementPtr = DataPtr;
                ListPtr->FrontPtr->Previous->Next = ListPtr->FrontPtr;
                ListPtr->FrontPtr->Previous->Previous = NULL;

                /* Assign newly initialized node as front node of LinkedList */
                ListPtr->FrontPtr = ListPtr->FrontPtr->Previous;
        }

        /* List size plus one */
        (ListPtr->NumElements)++;
}

void AddToBackOfLinkedList(LinkedLists *ListPtr, ElementStructs
        *DataPtr)
{
        /* If there are no other elements, create new node and add it,
         * assigning it to both the front and back pointers */
        if(ListPtr->NumElements == 0)
        {
                ListPtr->FrontPtr = malloc(sizeof(LinkedListNodes));
                ListPtr->FrontPtr->ElementPtr = DataPtr;
                ListPtr->FrontPtr->Next = NULL;
                ListPtr->FrontPtr->Previous = NULL;
                ListPtr->BackPtr = ListPtr->FrontPtr;
                /*printf("Adding %s\n", DataPtr->ElementValue);*/
        }

        /* If there are other elements, create new node and add it to the back
         * while retaining previous node order */
        else
        {
                /* Initialize new LinkedListNode */
                ListPtr->BackPtr->Next = malloc(sizeof(LinkedListNodes));
                ListPtr->BackPtr->Next->ElementPtr = DataPtr;
                ListPtr->BackPtr->Next->Previous = ListPtr->BackPtr;
                ListPtr->BackPtr->Next->Previous = ListPtr->BackPtr;
                ListPtr->BackPtr->Next->Next = NULL;

                /* Assign newly initialized node as back node of LinkedList */
                ListPtr->BackPtr = ListPtr->BackPtr->Next;
                printf("Adding %s\n", ListPtr->BackPtr->ElementPtr->ElementValue);
        }

        /* List size plus one */
        (ListPtr->NumElements)++;
}

ElementStructs *RemoveFromFrontOfLinkedList(LinkedLists *ListPtr)
{
        if(ListPtr->NumElements > 0)
        {
                ElementStructs *removedElement = ListPtr->FrontPtr->ElementPtr;
                LinkedListNodes *removedNode = ListPtr->FrontPtr;
                 if(ListPtr->NumElements == 1)
            {
                    ListPtr->FrontPtr = NULL;
            }
            else
            {
                    ListPtr->FrontPtr = ListPtr->FrontPtr->Next;
                    ListPtr->FrontPtr->Previous = NULL;
            }
            (ListPtr->NumElements)--;
            free(removedNode);
            return removedElement;
    }
    else
    {
            ElementStructs *nullElement = NULL;
            return nullElement;
    }
}

ElementStructs *RemoveFromBackOfLinkedList(LinkedLists *ListPtr)
{
        if(ListPtr->NumElements > 1)
        {
                ElementStructs *removedElement = ListPtr->BackPtr->ElementPtr;
                LinkedListNodes *removedNode = ListPtr->BackPtr;
                if(ListPtr->NumElements == 1)
                {
                        ListPtr->BackPtr = NULL;
                }
                else
                {
                        ListPtr->BackPtr = ListPtr->BackPtr->Previous;
                        ListPtr->BackPtr->Next = NULL;     
                }
                (ListPtr->NumElements)--;
                free(removedNode);
                return removedElement;
        }
        else
        {
                ElementStructs *nullElement = NULL;
                return nullElement;
        }
}


void DestroyLinkedList(LinkedLists *ListPtr)
{
        while(ListPtr->FrontPtr != NULL)
        {
                LinkedListNodes *removedNode = ListPtr->FrontPtr;
                ListPtr->FrontPtr = ListPtr->FrontPtr->Next;

                /* Deallocate element in node */
                free(removedNode->ElementPtr->ElementValue);
                free(removedNode->ElementPtr);

                /* Deallocate node */
                free(removedNode);
        }
        free(ListPtr);
}

TestList.c:

/******************************************************************************
 * Tests the functionality of the LinkedList specified in LinkedLists.h using
 * the file "american-english-words". Reads in individual words and stores them
 * as node elements in the LinkedList.
 * Written by xxxxx
 *****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LinkedLists.h"

#define MAX_LENGTH 100 /* Length of longest word in any major English dictionary */

int main(int argc, char** args)
{
        if(argc == 2)
        {
                /* Initialize LinkedList */
                LinkedLists *LL;

                /* File pointer to input file */
                FILE *fp;

                /* Node to store input data from file */
                ElementStructs *NodeData;

                /* Loop completion boolean */
                int Done;

                /* Loop position counter */
                int Position;

                /* Iterator */
                ElementStructs *CurElement;

                /* Open input file and check that it is readable. If not, exit */
                fp = fopen(args[1], "r");

                if(fp == NULL)
                {
                        fprintf(stderr, "File open failed.");
                        return 2;
                }

                /* Initialize linked list and other necessary variables */
                LL = malloc(sizeof(*LL));
                InitLinkedList(LL);

                Done = 0;
                Position = 0;

                do
                {
                        if(!feof(fp))
                        {
                                /* Allocate space for new node data */
                                NodeData = malloc(sizeof(ElementStructs));

                                /* Allocate space in node element for input string */
                                NodeData->ElementValue = malloc(MAX_LENGTH * sizeof(char));

                                /* Read new node data from file */
                                fscanf(fp, "%s", NodeData->ElementValue);

                                /* Assign scanned values to node elements */
                                NodeData->ElementPosition = Position;
                                /*strcpy(NodeData->ElementValue, readString);*/

                                /* Add data node to LinkedList */
                                AddToFrontOfLinkedList(LL, NodeData);
                        }
                        else
                                Done = 1;
                        Position++;
                }while(Done == 0);

                do
                {
                        CurElement = RemoveFromFrontOfLinkedList(LL);

                        if(CurElement != NULL)
                                printf("Word #%d: %s\n", CurElement->ElementPosition,
                                CurElement->ElementValue);
                }while(CurElement != NULL);

                /* Deallocate linked list */
                DestroyLinkedList(LL);
                fclose(fp);

        }
        /* Bad command line input */
        else
        {
                fprintf(stderr, "Incorrect number of arguments");
                return 1;
        }

        return 0;
}

The program compiles fine. However, running it causes a seg fault at the end of execution, and valgrind reports multiple memory leaks (Shown below). Please, if you have any help to offer, I would be extremely grateful. The issue is mostly in the RemoveFromBackOfLinkedList and RemoveFromFrontOfLinkedList methods in the LinkedList.c module. There's a block of code in the main module (TestList.c) that calls one of these functions (I've tried both, but they have nearly identical functionality, and neither works). The block is a do/while loop shown below:

do
                {
                CurElement = RemoveFromFrontOfLinkedList(LL);

                        if(CurElement != NULL)
                                printf("Word #%d: %s\n", CurElement->ElementPosition,
                                CurElement->ElementValue);
                }while(CurElement != NULL);

Valgrind Results:

Word #225921: stoich
.
.
.
.
Word #6: Cam's
Word #5: petrochemistry's
Word #4: Tera
Word #3: benedictions
Word #2: wisted
Word #1: toxins
==4849== Invalid write of size 8
==4849==    at 0x400B5C: RemoveFromFrontOfLinkedList (in /home/amb2189/hw3/TestList)
==4849==    by 0x40085B: main (in /home/amb2189/hw3/TestList)
==4849==  Address 0x10 is not stack'd, malloc'd or (recently) free'd
==4849== 
==4849== 
==4849== Process terminating with default action of signal 11 (SIGSEGV)
==4849==  Access not within mapped region at address 0x10
==4849==    at 0x400B5C: RemoveFromFrontOfLinkedList (in /home/amb2189/hw3/TestList)
==4849==    by 0x40085B: main (in /home/amb2189/hw3/TestList)
==4849==  If you believe this happened as a result of a stack
==4849==  overflow in your program's main thread (unlikely but
==4849==  possible), you can try to increase the size of the
==4849==  main thread stack using the --main-stacksize= flag.
==4849==  The main thread stack size used in this run was 8388608.
==4849== 
==4849== HEAP SUMMARY:
==4849==     in use at exit: 23,965,172 bytes in 413,185 blocks
==4849==   total heap usage: 619,775 allocs, 206,590 frees, 28,923,332 bytes allocated
==4849== 
==4849== 16 bytes in 1 blocks are possibly lost in loss record 1 of 9
==4849==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4849==    by 0x4007E2: main (in /home/amb2189/hw3/TestList)
==4849== 
==4849== 200 bytes in 2 blocks are possibly lost in loss record 5 of 9
==4849==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4849==    by 0x4007F0: main (in /home/amb2189/hw3/TestList)
==4849== 
==4849== 23,963,992 (3,305,392 direct, 20,658,600 indirect) bytes in 206,587 blocks are definitely lost in loss record 9 of 9
==4849==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4849==    by 0x4007E2: main (in /home/amb2189/hw3/TestList)
==4849== 
==4849== LEAK SUMMARY:
==4849==    definitely lost: 3,305,392 bytes in 206,587 blocks
==4849==    indirectly lost: 20,658,600 bytes in 206,586 blocks
==4849==      possibly lost: 216 bytes in 3 blocks
==4849==    still reachable: 964 bytes in 9 blocks
==4849==         suppressed: 0 bytes in 0 blocks
==4849== Reachable blocks (those to which a pointer was found) are not shown.
==4849== To see them, rerun with: --leak-check=full --show-reachable=yes
==4849== 
==4849== For counts of detected and suppressed errors, rerun with: -v
==4849== Use --track-origins=yes to see where uninitialised values come from
==4849== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)

解决方案

Make some changes in your 2 delete functions,,

ElementStructs *RemoveFromFrontOfLinkedList(LinkedLists *ListPtr)
{
        if(ListPtr->NumElements > 0)
        {
        /*      ElementStructs *removedElement = ListPtr->FrontPtr->ElementPtr;*/
                /*LinkedListNodes *removedNode = malloc(sizeof(removedNode)); // no need allocate because you are deleting the node
                removedNode = ListPtr->FrontPtr;*/ 
                LinkedListNodes *removedNode = ListPtr->FrontPtr; // use this line
                ListPtr->FrontPtr = ListPtr->FrontPtr->Next;
                ListPtr->FrontPtr->Previous = NULL;
                free(removedNode);
                (ListPtr->NumElements)--;
                return NULL;
        }
        else
        {
                ElementStructs *nullElement = NULL;
                return nullElement;
        }
}

ElementStructs *RemoveFromBackOfLinkedList(LinkedLists *ListPtr)
{
        if(ListPtr->NumElements != 0)
        {
                ElementStructs *removedElement = ListPtr->BackPtr->ElementPtr;
                LinkedListNodes *removedNode = ListPtr->BackPtr;
                ListPtr->BackPtr = ListPtr->BackPtr->Previous;
                ListPtr->BackPtr->Next = NULL;
                free(removedNode);
                (ListPtr->NumElements)--; // add this line
                return removedElement;
        }
        else
        {
                ElementStructs *nullElement = NULL;
                return nullElement;
        }
}

EDIT 1

CurElement = malloc(sizeof(*CurElement)); this is another mem-leak in main, you don't have to use malloc for it, just remove this line.

EDIT 2: Why aren't you freeing your ELEMENT and ELEMENTVALUE...?

do
{
        CurElement = RemoveFromFrontOfLinkedList(LL);

        if(CurElement != NULL) {
                printf("Word #%d: %s\n", CurElement->ElementPosition,
                CurElement->ElementValue);
                free(CurElement->ElementValue);  //add these 2 line to free ELEMENTVALUE And ELEMENT.
                free(CurElement);
        }
}while(CurElement != NULL);

这篇关于用C链表内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆