c语言链表空间分配的问题,邀请诸位高手共析~

一个链表分配的问题,请诸君共析,如何对一个节点进行分配空间,简而言之可能说是malloc和free方面的问题。
程序中链表创建函数、打印、逆序都没有问题,在删除时出现问题,原因是之前对节点的分配是s=(pNode)malloc(sizeof(pNode))。由于只是在删节点时出现问题,所以奇怪,特此请高人指点。谢谢~
程序如示:
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct LinkList
{
int data;
struct LinkList *next;
}Node,*pNode; //这里有两种定义 LinkList 和Node 、*pNode同名

pNode create() //创建链表函数
{
pNode head, p,s;
int cycle = 1;
int x = 0;
head = (pNode)malloc(sizeof(Node));
head->next = NULL;
p = head;
while(cycle)
{
printf("please intput the data \n");
scanf("%d",&x);
if (x !=0 )
{
s = (pNode)malloc(sizeof(Node)); /*注意这里分配模式,若分配为 s=(pNode)malloc(sizeof(pNode))的形式,在后面释放链表指针时会报错*/
s->data = x; /*如果s=(pNode)malloc(sizeof(pNode))只是分配了一个指针的空间,那为何还有s->data=x一说?*/
p->next = s;
p = p->next;
}
else
{
p->next = NULL;
cycle = 0;
}
}
s = head;
head = head->next;
free(s);
return head;
}

int length(pNode head) //求链表长度
{
pNode p;
int n = 0;
p = head;
while(p != NULL)
{
p = p->next;
n++;
}
return n;
}

void print(pNode head) //打印链表
{
pNode p;
p = head;
printf("\nthe Linklist is :");
while (p!=NULL)
{
printf("\t%d ",p->data);
p = p->next;
}
}

pNode deletelist1(pNode &head, int num) //删除链表节点
{
pNode p,temp;
int len;
p = head;
len = length(head);
num--;
if (num>len)
{
printf("\nthe scale is exceeded!");
return head;
}
else
printf("\nwait to delete the number needed……");
while(--num)
{
p = p->next;
}
temp = p;
p = p->next;
temp->next = p->next;
free (p); /*就是这里,若是之前按照s=(pNode)malloc(sizeof(pNode))分配空间 ,那么运行会报after normal block的错误,应该是指针内存方面的错误*/
return head;
}

void reverse(pNode &head) //逆序链表
{
pNode p,s,t;
s = head;
p = head->next;
while(p!=NULL)
{
t = p ;
p = p->next;
t->next = s;
s = t;
}
head->next=NULL;
head = s;
}

void main()
{
pNode head1;
head1 = create();
print(head1);

reverse(head1);
print(head1);
deletelist1(head1,3); //报错 after normal block (#46) 有时(#47)
print(head1);
}

s=(pNode)malloc(sizeof(pNode))只申请了一个指针空间。故而后面free(s),因为找不到s指向的Node节点空间。而报错。
申请一个pNode的空间,返回一个pNode型指针s,。s->next = s是指针s的强制性操作未知空间(指针是C的精华,也是缺点。)。也就是操作了s指向空间(开始的前四个为data,后四个为next.实际上,系统不认可,所以释放报错)。你可以强制性输出s里面的内容看看。
printf("data:[%d] next:[%p]\n",s->data,s->next);
不知道说明白了没有。不明白可以追问。追问

是的,只申请了一个Node型指针的空间,按理说我在给s->data赋值的时候,如s->data = 2;不是已经相当于强行占用了内存吗,因为原本根本没有空间存放s-data,也就是这个2,但是为什么创建时,强行占用内存不报错,释放时才报错呢?鄙人愚钝,望不吝赐教。谢谢~

追答

你申请了一个Node型指针空间(4个字节),返回了pNode指针s。也就是pNode指针s所指向的空间地址开始,长度为4个字节。是s可以正确操作的空间,s->data就放在了那四个空间里面。没有强占内存。
接着p->next = s; //把pNode型指针s赋值给p->next。
p = p->next;//看起来没问题。但实际上s中没申请出next的空间,你后面接着构建链表。p->next = s;就是指针p强行访问了没有权限的空间(也就是访问了没申请出来的next空间,即p->next = s)。但是构建出来的是错误的链表。当你free时,系统就从s指向的空间开始。长度为sizeof(Node),欲将其释放,所以释放了没malloc的空间而报错。
指针是程序里面一个特殊的存在,可以强行操作内存。是好处也是坏处。容易出现段错误。

温馨提示:内容为网友见解,仅供参考
第1个回答  2012-09-11
我这边用的VC6 运行正常

please intput the data
11
please intput the data
33
please intput the data
44
please intput the data
55
please intput the data
66
please intput the data
77
please intput the data
0

the Linklist is : 11 33 44 55 66 77
the Linklist is : 77 66 55 44 33 11
wait to delete the number needed……
the Linklist is : 77 66 44 33 11 Press any key to cont
inue本回答被网友采纳
第2个回答  2012-09-11
s=(pNode)malloc(sizeof(pNode)) 这一句只申请一块存放指向struct指针的内存,逻辑上错误,
至於 s->data为什麽有意义。因为这个指针是类型是Node。

c语言链表空间分配的问题,邀请诸位高手共析~
一个链表分配的问题,请诸君共析,如何对一个节点进行分配空间,简而言之可能说是malloc和free方面的问题。程序中链表创建函数、打印、逆序都没有问题,在删除时出现问题,原因是之前对节点的分配是s=(pNode)malloc(sizeof(pNode))。由于只是在删节点时出现... 展开 qian8329522 | 浏览1079 次 |举报 我有更好的答...

相似回答