数组越界导致的数据异常

写了一个顺序表插入的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]; /* 向量data用于存放表结点 */
int length; /* 当前的表长度 */
};

void Initlist(struct Seqlist *L)
{
memset(L, 0, sizeof(int) * Listsize);
L->length = 0;
}

/* 将新结点x插入L所指的顺序表的第i个结点ai的位置上 */
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++;

验证

得到正确结果