写了一个顺序表插入的demo,结果显示异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <stdio.h> #include <windows.h> #define Listsize 10
struct Seqlist { int data[Listsize]; int length; };
void Initlist(struct Seqlist *L) { memset(L, 0, sizeof(int) * Listsize); L->length = 0; }
void Insert(struct Seqlist *L, int data, int index) { if (index < 0 || index > Listsize) { printf("error\n"); return; } for (int i = L->length; i >= index; i--) L->data[i + 1] = L->data[i]; L->data[index] = data; L->length++; }
void Print(struct Seqlist *L) { for (int i = 0; i < Listsize; i++) printf("%d ", L->data[i]); printf("L->length:%d ", L->length); printf("\n"); }
void main() { struct Seqlist *L; L = (struct Seqlist *)malloc(sizeof(struct Seqlist)); Initlist(L); for (int i = 0; i < Listsize; i++) { Insert(L, i, i); Print(L); } }
|
输出
这个异常就很莫名奇妙,期望的结果应该最后一栏,结构体的length长度应该是10,结果却是1;从输出可以看到,前9项都正常,最后一项,很诡异,9自加1得1
分析
我插入的方式是,统一是把要插入的这个点以后的全部的数据全部后移一格,腾出一格插入数据
结构体的内存图
length应该是跟在数组后面,程序实际上是把data[9]赋给了data[10],而data[10]已经越界了,data[10]就是length,虽然越界了,但指针还是能这样操作;就是把数组最后一个0付给length,然后0+1=1;就看到了这样的输出结果
进调试查看一下位置
和预想的一样,通过检查,发现循环检测的条件不对,当index==L->length时,循环应该跳出,不应该进行操作;修改为
1 2 3 4
| for (int i = L->length; i > index; i--) L->data[i + 1] = L->data[i]; L->data[index] = date; L->length++;
|
验证
得到正确结果