c语言链表 内存释放
在晚上看了一个视频里面写了链表,但是有几个疑问
第一个疑问:main函数里的malloc没有释放,我加入了free为啥会在ShowData函数那里出错?
第二个疑问:在初始化的时候为啥要用二级指针呢?直接传入list指针不可以吗?而且这个也没有释放,为啥释放了还是错的
程序在下面:
头文件:list.h
pragma once //保证只被编译一次
include <stdlib.h>
include <stdio.h>
//数据
typedef struct DATA
{
int x;
int y;
}Data;
//结点
typedef struct NODE
{
Data data;
struct NODE *pnext;
}Node;
//链表
typedef struct LIST
{
Node* pfront; /* 第一个结点指针/
Node prear; /* 最后一个结点指针/
int count; / 结点的个数*/
}List;
int ListInit(List pplist);
void TraverList(List plist, void(Traver)(Node pnode));
int IsEmpty(List plist);
void InserList(List* plist, Node* pnode);
void ShowData(Node * pnode);
源文件:
list.cpp
//*************************************************************************
// 创建日期: 2022-4-1
// 文件名称: list.cpp
// 创建作者: [你的名字]
// 相关说明: 链表
// 修改说明:
// 运行环境:
//*************************************************************************
//-------------------------------------------------------------------------
include "list.h"
int ListInit(List** pplist)
{
//************************************
// Method: ListInit
// FullName: ListInit
// Access: public
// Returns: int
// Qualifier: 初始化链表,成功返回1 否则返回 0
// Parameter: List * * pplist
//************************************
*pplist = (List *)calloc(1, sizeof(List));
if (NULL == *pplist)
{
printf("申请空间失败");
printf("请按任意键退出");
getchar();
return 0;
}
else
{
(*pplist)->pfront = NULL; /*让链表里的指向结点的指针指向空*/
(*pplist)->prear = NULL;
(*pplist)->count = 0;
}
//free(pplist);
return 1;
}
void TraverList(List plist,void(Traver)(Node* pnode))
{
//************************************
// Method: TraverList
// FullName: TraverList
// Access: public
// Returns: void
// Qualifier: 用于遍历参数并且对链表做操作
// Parameter: List * plist 指向链表的指针
// Parameter: void
// Parameter: * Traver 指向函数的指针 指针:Traver (利用函数名对其赋值) 参数:Node类型 返回值:void
// Parameter: Node * pnode
//***********************************
Node ptemp = plist->pfront;
int listsize = plist->count;
while (listsize)
{
Traver(ptemp); /用的时候直接用指针表示函数*/
ptemp = ptemp->pnext;
listsize--;
}
}
int IsEmpty(List* plist)
{
if (plist->count == 0)
return 1;
else
return 0;
}
void InserList(List* plist, Node* pnode)
{
//************************************
// Method: InserList
// FullName: InserList
// Access: public
// Returns: void
// Qualifier: 对链表进行插入,将pnode结点插入plist链表
// Parameter: List * plist 指向链表的结点
// Parameter: Node * pnode 待插入的结点
//************************************
if (IsEmpty(plist)) /链表是空的/
plist->pfront = pnode;
else
plist->prear->pnext = pnode; /尾插法/
plist->prear = pnode;
plist->count++;
}
void ShowData(Node * p_node)
{
printf("x = %d\t y = %d\n", p_node->data.x, p_node->data.y);
}
主函数
main.cpp
include "list.h"
include <time.h>
int main()
{
List *pList; /*定义一个指针*/
ListInit(&pList); /*对链表进行初始化*/
srand((unsigned)time(NULL));
for (int i = 0; i < 6; i++)
{
Node *pnode = (Node *)calloc(1, sizeof(Node)); /*制造结点*/
pnode->data.x = i;
pnode->data.y = i;
pnode->pnext = NULL; /*结点不指向下一个结点*/
InserList(pList, pnode);
// free(pnode);
// pnode = NULL;
}
TraverList(pList, ShowData);
getchar();
}
回答
在这里二级指针,是为了把*Plist得地址传过去,这样做是因为moloc是为地址开辟内存,所以要把地址传过去。如果你List *pList定义成 List PList 函数里就用一级指针。
你在访问前都释放了对象,还怎么访问。