今天闲着没事实现了一下数据结构里面的顺序表,在顺表初始创建的时候遇到了这样一个问题。
#include<stdlib.h>
#include<stdio.h>
#define MaxSize 1000
#define ElemType int
typedef struct
{
ElemType data[MaxSize];
int length;
}SqList;
int isListEmpty(SqList *L);
int *p;
void CreateList(SqList *LTMP,ElemType a[],int n){
printf("%p ",LTMP);
LTMP=(SqList *)malloc(sizeof(SqList));
printf("%p ",LTMP);
p=(int *)LTMP;
printf("%p\n",p);
for(int i=0;i<n;i++)
(*LTMP).data[i]=a[i];
(*LTMP).length=n;
}
void dispList(SqList *L){
if(isListEmpty(L))
return;
for(int i=0;i<L->length;i++){
printf("%d ",L->data[i]);
}
printf("\n");
}
int isListEmpty(SqList *L){
return(L->length==0);
}
int main()
{
int a[3]={1,2,3};
SqList * L=NULL;
printf("%p ",L);
CreateList(L,a,3);
printf("%d %d %d \n",*p,*(p+1),*(p+2));
printf("%p\n",L);
//dispList(L);
}
当你在CreateList(SqList *L,ElemType a[],int n)里,不对L加上&(引用符)将会导致dispList函数报错,原因是这里的CreateList函数里L传递的是形参,CreateList函数的L指针是一个临时指针,设为LTMP。哪怕是指针,没有引用符,传递的也是形参,L是两个指针。
第一个地址表示实参L的地址,因为L为NULL,所以地址为0地址。第二个地址为L的传递给CreateList函数的形式参数,LTMP一样指向NULL,同样为0地址。
第三个地址由于给LTMP分配了新的内存空间,指向malloc开辟的一段动态内存,首地址为000...00337000,第四个地址是全局变量指针P指向LTMP的地址,也为000...00337000。但是当函数运行结束后,调用函数栈为空,临时变量也被释放,那段内存一直没有被释放。
后面用*p,*(p+1),*(p+2)输出1,2,3,即在CreateList赋的值,那段内存一直没有释放了,里面存的数据也没有改变,如果没有内存只想它,就会出现内存泄露。
后面再输出L的地址,由于是值传递,所以L没有改变,依旧是0地址。
下面我们用 引用传递来看看。
#include<stdlib.h>
#include<stdio.h>
#define MaxSize 1000
#define ElemType int
typedef struct
{
ElemType data[MaxSize];
int length;
}SqList;
int isListEmpty(SqList *L);
int *p;
void CreateList(SqList *&L,ElemType a[],int n){
printf("%p ",L);
L=(SqList *)malloc(sizeof(SqList));
printf("%p ",L);
p=(int *)L;
printf("%p\n",p);
for(int i=0;i<n;i++)
L->data[i]=a[i];
L->length=n;
}
void dispList(SqList *L){
if(isListEmpty(L))
return;
for(int i=0;i<L->length;i++){
printf("%d ",L->data[i]);
}
printf("\n");
}
int isListEmpty(SqList *L){
return(L->length==0);
}
int main()
{
int a[3]={1,2,3};
SqList * L=NULL;
printf("%p ",L);
CreateList(L,a,3);
printf("%d %d %d \n",*p,*(p+1),*(p+2));
printf("%p\n",L);
dispList(L);
}
第一二个地址都是L的地址,没有变化,所以依旧是0地址。后面用malloc函数传给动态分配内存的首地址,并且由于传递了L的实参,L发生了改变,所以三四五地址同为新分配的地址。dispList函数可以正常运行了。