1、数组越界的访问
数组越界访问是指试图访问数组中不存在的元素,如在声明了大小为 5
的数组中访问 array[5]
或更高的索引(数组索引从 0
开始,因此有效索引是 0
到 4
)。
#include <stdio.h>
int main() {
int array[5] = {0, 1, 2, 3, 4};
printf("array[6] = %d\n", array[6]); // 越界访问,未定义行为
return 0;
}
2、数组越界访问异常问题
数组越界访问被视为未定义行为,也就是编译器和系统可能以任何方式处理它,可能出现下面的情况。
1)数据损坏
访问或修改数组之外的内存可能会影响程序的其他数据。
2)程序崩溃
访问无效内存可能会导致段错误(Segmentation Fault)或访问冲突(Access Violation)。
3)安全漏洞
恶意攻击者可能利用这种漏洞篡改内存,从而执行任意代码(比如缓冲区溢出攻击)。
4)不可预测的行为
程序可能表现出不可预测的行为,不同的编译器或不同的运行环境下结果也可能不同。
3、数组越界访问示例
1)段错误(Segmentation Fault)
访问未分配的内存会导致段错误,这是操作系统的保护机制,防止程序非法访问受保护的内存区域。
#include <stdio.h>
int main() {
int array[5];
int value = array[1000]; // 大幅越界,可能导致段错误
return 0;
}
2)数据损坏或覆盖
如果数组越界访问的地址有效,程序可能继续运行,但会破坏其他数据,因可能在意外修改其他变量的值。
#include <stdio.h>
int main() {
int array[5];
int anotherVar = 42;
// 越界,可能会覆盖 anotherVar 的值
array[6] = 99;
return 0;
}
3) 缓冲区溢出漏洞
缓冲区溢出是因为超出数组范围写入数据,可能导致攻击者控制程序流。攻击者可以通过精心构造的数据覆盖返回地址,执行恶意代码。
4、避免数组越界访问方法
1)使用正确的索引范围
始终确保数组索引在合法范围内。使用循环时要特别小心,不要超过数组的大小。
#include <stdio.h>
int main() {
int array[5];
for (int i = 0; i < 5; i++) {
array[i] = i; // 确保索引范围在 0 到 4 之间
}
return 0;
}
2)使用 sizeof 检查数组大小
在无法确定数组大小的情况下,可以使用 sizeof
来计算数组的元素数量。
#include <stdio.h>
int main() {
int array[5];
int size = sizeof(array) / sizeof(array[0]);
for (int i = 0; i < size; i++) {
array[i] = i;
}
return 0;
}
3)动态分配数组时小心边界
使用动态内存分配时,确保释放的内存不会被非法访问。
#include <stdio.h>
int main() {
int *array = (int *)malloc(5 * sizeof(int));
if (array != NULL) {
for (int i = 0; i < 5; i++) {
array[i] = i;
}
free(array);
}
return 0;
}