大哥大姐们帮帮忙!!!free()函数的疑惑,从单链表中删除结点时报错.

yangfasheng 2005-06-01 05:00:42

如题:
// 问题出在删除结点函数中,其它几个函数是测试时的辅助模块

下面是源代码,编译器 VC6.0

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

#define FALSE 0
#define OK 1
typedef char * DataType;
typedef struct Link
{
DataType Data;
struct Link *next;
}Link;

void display( Link *L); /* 显示单链表中各结点的字符串数据 */
Link *CreateHeadNode(); /* 创建表头结点 */
int DeleteData(Link *head, DataType data);/* 删除一个指定数据的结点 */
int InsertRear( Link *L, DataType data );/* 在单链表表尾插入一个新结点 */

int main(int argc, char* argv[])
{
Link *head=NULL;
int i=0,status=0;

char *stra[7] = {"te","c","g","fa","b","d","abc"};

if( (head=CreateHeadNode()) == NULL) return 0;

/* 建一个单链表,测试 */
for( i=0; i<7; i++)
{
status = InsertRear(head,stra[i]);
if( status == 0 )return 0;
}
display(head);

/* 删除一个结点 */
if( DeleteData(head,"fa") != OK )
return 0;
display(head);

return 0;
}

/****************************************************************************************/
int DeleteData(Link *head, DataType data)
{
Link *q;
Link *p = head->next ;
if( p == NULL )
{
return FALSE;
}

q = head;
for( ; p != NULL; )
{
if( strcmp(p->Data ,data) ==0 )/* 字符串相等时删除该结点 */
{
q->next = p->next ; //暂时保存;

p->next = NULL;
/**********************************************************/
/*
** s = (Link *)malloc( sizeof(Link) );
** s->Data = (DataType )malloc( strlen(data) );
** 我在创建结点时,数据域用 malloc() 函数来分配一个空间,
** 用于存放字符串,在删除该结点时,按理应该先释放该内存空间,
** 然后再用 free( p ), 来释放该结点所占的内存;
** 为什么在删除该结点时,我用语句free( p->Data );
** 释放存储字符的内存时会出错???? 如果不释放该内存应该会产生内存泄漏
**
** 恳请XDJM 指点迷津;
*/
// free( p->Data ); /* 去掉注释就报错 */
/**********************************************************/
free(p);
return OK;
}
q = p;
p = p->next ;
}

printf("The Link has no the data!\n");
return FALSE;
}

void display( Link *L) /* 显示单链表中各结点的字符串数据 */
{
Link *p=NULL;

printf("The Data of the single Link is the Flowing:\n");
if( L->next == NULL )
{
printf("The Single Link is empty !\n");
return;
}

for( p = L->next ; p != NULL; )
{
printf(" %-7s ",p->Data );
p = p->next ;
}
printf(" End put !\n\n");
}

Link *CreateHeadNode() /* 创建表头结点 */
{
Link *head;
head = (Link *)malloc(sizeof(Link));
if( head == NULL )
{
printf("新结点创建失败!\n");
return NULL;
}
head->Data = 0;
head->next = NULL;

return head;
}

int InsertRear( Link *L, DataType data )/* 在单链表末尾插入一个结点 */
{
Link *p, *s ;

for( p = L ; p->next != NULL; )
{
p = p->next ;
}
s = (Link *)malloc( sizeof(Link) );
s->Data = (DataType )malloc( strlen(data) );
if( s == NULL || s->Data == NULL )
{
printf("新结点创建失败!\n");
return FALSE; /* 存储分配失败 */
}
strcpy(s->Data,data); /* 将数据复制到新建的结点中 */
s->next = p->next ;
p->next = s;

return OK;
}
...全文
158 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhousqy 2005-06-02
  • 打赏
  • 举报
回复
回复人: Michael_555(Sell Myself) ( ) 信誉:100 2005-6-1 17:32:31 得分: 0



InsertRear()函数中的

s->Data = (DataType )malloc( strlen(data) );

改成:

s->Data = (DataType )malloc( sizeof(DataType) * strlen(data) );

就可以了。
------------
你错了。


我找到原因啦!
s->Data = (DataType )malloc( strlen(data) );
应该是改成:
s->Data = (DataType )malloc( strlen(data)+1 );
因为strlen(data)只是字符串中实际字符的个数,
但是,每个字符串的末尾必须有一个结束字符'\0';
否则编译器将无法知道字符串的结束位置!
也就没法释放这一个内存空间啦!

哈哈,我成啦!!!!!!!!!!!
------------------
不错,不错。


yangfasheng 2005-06-01
  • 打赏
  • 举报
回复
真是太大意啦,
平时也总会提醒自己应该留意这些细节,
可程序写出来还是有这么多隐患!


谢谢几位朋友
没有你们的提示,我可能还要花好多时间!

zloves 2005-06-01
  • 打赏
  • 举报
回复
mark
yangfasheng 2005-06-01
  • 打赏
  • 举报
回复

我找到原因啦!
s->Data = (DataType )malloc( strlen(data) );
应该是改成:
s->Data = (DataType )malloc( strlen(data)+1 );
因为strlen(data)只是字符串中实际字符的个数,
但是,每个字符串的末尾必须有一个结束字符'\0';
否则编译器将无法知道字符串的结束位置!
也就没法释放这一个内存空间啦!

哈哈,我成啦!!!!!!!!!!!
yangfasheng 2005-06-01
  • 打赏
  • 举报
回复
回复人: Michael_555(Sell Myself) ( ) 信誉:100 2005-06-01 17:32:00 得分: 0

InsertRear()函数中的

s->Data = (DataType )malloc( strlen(data) );

改成:

s->Data = (DataType )malloc( sizeof(DataType) * strlen(data) );
=======================================
s->Data = (DataType )malloc( sizeof(DataType) * strlen(data) );


上面这条语句我就不太明白啦,上面的朋友能否解释一下????/

一般来说,存放一个字符一个字节就可以啦,
如果还要乘上sizeof(DataType)=4 ( 32 bit OS)
那岂不是多占用空间,这样好象不太合理吧?

yangfasheng 2005-06-01
  • 打赏
  • 举报
回复
太好了,有这么多朋友帮忙.
非常感谢几位朋友的回答,

回复人: yangyouyi(yangyouyi) ( ) 信誉:95 2005-06-01 17:17:00 得分: 0


************
free的只能是地址。可以你虽然定义了DataType但是系统不认为它是地址类型的。


=============================
我认为,上面这条语句其实与:
char *data = "malloc";
char *str = (char *)malloc(strlen(data));
free(str);

应该没有差别啊,为什么系统对它们在处理时有不同反应呢?
其实觉得
s->Data = (DataType )malloc( strlen(data) );
也应该是为s->Data分配了一个用来存放字符串"fa"的内存空间啊,
Michael_555 2005-06-01
  • 打赏
  • 举报
回复
InsertRear()函数中的

s->Data = (DataType )malloc( strlen(data) );

改成:

s->Data = (DataType )malloc( sizeof(DataType) * strlen(data) );

就可以了。


Michael_555 2005-06-01
  • 打赏
  • 举报
回复
再汗,匪徒还是错了!
Michael_555 2005-06-01
  • 打赏
  • 举报
回复
yangyouyi(yangyouyi)

s->Data = (DataType )malloc( strlen(data) );
************
free的只能是地址。可以你虽然定义了DataType但是系统不认为它是地址类型的。
===================================================================


typedef char * DataType;
DataType在编译的时候就会被char*替换的。
zhousqy 2005-06-01
  • 打赏
  • 举报
回复
s->Data = (DataType )malloc( sizeof(*DataType) * strlen(data) );
zhousqy 2005-06-01
  • 打赏
  • 举报
回复
horce's, 写错了,汗。
zhousqy 2005-06-01
  • 打赏
  • 举报
回复
s->Data = (DataType )malloc( strlen(data) );
-----------------------------------
s->Data = (DataType )malloc( strlen(*DataType) );
Michael_555 2005-06-01
  • 打赏
  • 举报
回复
在DEV-C++上没有问题啊。
walkany 2005-06-01
  • 打赏
  • 举报
回复
s->Data = (DataType )malloc( strlen(data) );
************
free的只能是地址。可以你虽然定义了DataType但是系统不认为它是地址类型的。

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧