有學生調程序,是要建順序表。
他的程序是這樣的:
~~~
#include <stdio.h>
#include <malloc.h>
#define MaxSize 50 //Maxsize將用于后面定義存儲空間的大小
typedef int ElemType; //ElemType在不同場合可以根據問題的需要確定,在此取簡單的int
typedef struct
{
ElemType data[MaxSize]; //利用了前面MaxSize和ElemType的定義
int length;
} SqList;
//聲明自定義函數
SqList InitList(SqList *L); //初始化順序表
void ListInsert(SqList *L,int i,int b); //插入函數
void DispList(SqList *L); //輸出函數
bool ListEmpty(SqList *L);//判定是否為空表ListEmpty(L)
int main()
{
SqList *sq;
InitList(sq);
ListInsert(sq, 1, 5);
ListInsert(sq, 2, 3);
ListInsert(sq, 1, 4);
DispList(sq);
return 0;
}
//輸出線性表DispList(L)
void DispList(SqList *L)
{
int i;
if (ListEmpty(L))
return;
for (i=0; i<L->length; i++)
printf("%d ",L->data[i]);
printf("\n");
}
//判定是否為空表ListEmpty(L)
bool ListEmpty(SqList *L)
{
return(L->length==0);
}
//初始化順序表InitList(*L)
SqList InitList(SqList *L)
{
L=(SqList *)malloc(sizeof(SqList));//這里申請了結點空間
L->length=0;
return *L;
}
void ListInsert(SqList *L,int i,int b) //插入函數
{
int j,k;
if(i<1)
{
printf("插入位置非法/n");
}
for(j=L->length; j>i; j--)
{
L->data[j]=L->data[j-1];
}
L->data[i]=b;
L->length++;
}
~~~
運行結果是這樣的:

他找我幫忙。基本可以斷定,內存使用不當,有溢出。
看一下編譯提示的信息,有一個警告:
D:\CB\DS\main.cpp|21|warning: ‘sq’ is used uninitialized in this function [-Wuninitialized]|
說在21行,sq未經初始化就使用了。通俗的說法,野指針。
圍繞著sq找。在main()函數中有:
~~~
SqList *sq;
InitList(sq);
~~~
這里在調用InitList時,實際參數sq就是野指針。但這還不是出問題的關鍵,看InitList函數的定義是:
~~~
//初始化順序表InitList(*L)
SqList InitList(SqList *L)
{
L=(SqList *)malloc(sizeof(SqList));//這里申請了結點空間
L->length=0;
return *L;
}
~~~
調用時,L得到的是野指針,但在函數里為其分配空間了。但調用完,這個地址并未返回到main函數中。調用完InitList,sq仍然還是野指針。這是關鍵!
沿這個思路,希望能將分配的空間地址能返回給main函數。return *L就不合適了,return L是返回地址。于是,函數定義改為:
~~~
//初始化順序表InitList(*L)
SqList *InitList(SqList *L)
{
L=(SqList *)malloc(sizeof(SqList));//這里申請了結點空間
L->length=0;
return L;
}
~~~
既然參數SqList *L調用時給的是個野指針,不要也罷。于是改選成無參函數:
~~~
//初始化順序表InitList(*L)
SqList *InitList()
{
SqList *L=(SqList *)malloc(sizeof(SqList));//這里申請了結點空間
L->length=0;
return L;
}
~~~
在調用時,main函數定義為:
~~~
int main()
{
SqList *sq;
sq = InitList();
ListInsert(sq, 1, 5);
ListInsert(sq, 2, 3);
ListInsert(sq, 1, 4);
DispList(sq);
return 0;
}
~~~
為保證程序能夠正確編譯,函數聲明等處的語法問題不一一列出。解決了這一環節的問題,程序能夠運行了,但結果:

斷定問題出在ListInsert函數中。看調用,插入的位置用的是邏輯序(從1開始記數),但函數定義中,直接L->data[i]=b;沒有考慮物理存儲中,下標是從0開始的。
所以,在ListInsert中加入一個 i–,完成邏輯序號向物理序號的轉換,Done。
正確的結果不貼圖了,最后改過的程序是:
~~~
#include <stdio.h>
#include <malloc.h>
#define MaxSize 50 //Maxsize將用于后面定義存儲空間的大小
typedef int ElemType; //ElemType在不同場合可以根據問題的需要確定,在此取簡單的int
typedef struct
{
ElemType data[MaxSize]; //利用了前面MaxSize和ElemType的定義
int length;
} SqList;
//聲明自定義函數
SqList *InitList(); //初始化順序表
void ListInsert(SqList *L,int i,int b); //插入函數
void DispList(SqList *L); //輸出函數
bool ListEmpty(SqList *L);//判定是否為空表ListEmpty(L)
int main()
{
SqList *sq;
sq = InitList();
ListInsert(sq, 1, 5);
ListInsert(sq, 2, 3);
ListInsert(sq, 1, 4);
DispList(sq);
return 0;
}
//輸出線性表DispList(L)
void DispList(SqList *L)
{
int i;
if (ListEmpty(L))
return;
for (i=0; i<L->length; i++)
printf("%d ",L->data[i]);
printf("\n");
}
//判定是否為空表ListEmpty(L)
bool ListEmpty(SqList *L)
{
return(L->length==0);
}
//初始化順序表InitList(*L)
SqList *InitList()
{
SqList *L=(SqList *)malloc(sizeof(SqList));//這里申請了結點空間
L->length=0;
return L;
}
void ListInsert(SqList *L,int i,int b) //插入函數
{
int j;
if(i<1)
{
printf("插入位置非法/n");
}
i--;
for(j=L->length; j>i; j--)
{
L->data[j]=L->data[j-1];
}
L->data[i]=b;
L->length++;
}
~~~