关于free释放内存

本文分享了《C程序设计教程》第二版中关于链表操作的代码实例,重点介绍了链表的插入和删除功能,并针对书中一处错误进行了修正说明。

最近将C程序设计教程(C How To Program)第二版

书上12-3的例子敲上电脑

程序如下:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>


struct listNode {
char data;
struct listNode * nextPtr;
};

typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;

void insert (LISTNODEPTR *, char);
char deletex (LISTNODEPTR *, char);
int isEmpty (LISTNODEPTR);
void printList (LISTNODEPTR);
void instructions (void);

int main ()
{
LISTNODEPTR startPtr = NULL;
int choice;
char item;

instructions ();
printf ("?");
scanf ("%d", &choice);

while (choice != 3)
{

switch (choice)
{
case 1:
printf ("Enter a character:");
scanf ("/n%c", &item);
insert (&startPtr, item);
printList (startPtr);
break;
case 2:
if (! isEmpty (startPtr))
{
printf ("Enter character to be deleted:");
scanf ("/n%c", &item);

if (deletex (&startPtr, item))
{
printf ("%c deleted. /n", item);
printList (startPtr);
}
else
printf ("%c not found. /n /n", item);
}
else
printf ("List is empty./n/n");

break;

default:
printf ("Invalid choice. /n /n");
instructions ();
break;

}

printf ("?");
scanf ("%d", &choice);
}

printf ("End of run. /n");
return 0;
}


void instructions (void)
{
printf ("Enter your choice: /n"
"1 to insert an element into the list. /n"
"2 to delete an element from the list. /n"
"3 to end. /n");
}

void insert (LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR newPtr, previousPtr, currentPtr;
//newPtr = (LISTNODEPTR)malloc (sizeof (LISTNODE));

newPtr = malloc (sizeof (LISTNODEPTR));

if (newPtr != NULL)
{
newPtr->data = value;
newPtr->nextPtr = NULL;

previousPtr = NULL;
currentPtr = *sPtr;

while (currentPtr != NULL && value > currentPtr->data)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}

if (previousPtr == NULL)
{
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}
else
{
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
printf ("%c not inserted. No memory available. /n", value);
}


char deletex (LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR previousPtr, currentPtr, tempPtr;

if (value == (*sPtr)->data)
{
tempPtr = *sPtr;
*sPtr = (*sPtr)->nextPtr;
free (tempPtr);
return value;
}
else
{
previousPtr = *sPtr;
currentPtr = (*sPtr)->nextPtr;

while (currentPtr != NULL && value != currentPtr->data)
{
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}

if (currentPtr != NULL)
{
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free (tempPtr);
return value;
}
}

return '/0';
}

int isEmpty (LISTNODEPTR sPtr)
{
return sPtr == NULL;
}

void printList (LISTNODEPTR currentPtr)
{
if (currentPtr == NULL)
printf ("List is empty. /n/n");
else
{
printf ("The list is: /n");

while (currentPtr != NULL)
{
printf ("%c-->", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}

printf ("NULL /n/n");
}
}

在运行插入的时候没问题

不过删除的时候就出问题了

调试发现时运行的free(tempPtr);出问题的

最后发现是书上打错了

就是申请结点空间的那句:

newPtr = malloc (sizeof (LISTNODEPTR));
应该改为:

newPtr = (LISTNODEPTR)malloc (sizeof (LISTNODE));

申请的应该是结构体的空间

而不是指向结构体的指针的空间

本人水平有限,一时没看出来
纠结了老半天

改了之后就没问题了

最后再说下

因为碰到释放内存错误

所以我也查了下

free只能释放堆内存

不能释放栈内存

其实堆栈我也不大理解

不过暂时理解是这样子

堆内存是使用malloc动态分配的内存空间

栈内存就是使用int等这些关键字申请的空间

运行图片如下:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值