关于数组越界的一些保护措施

不知道你有没有发现过即使你有时数组越界也不会引发错误。。。这是为什么呢?

当你在程序中连续申请两块内存时,有没有认真计算过返回的地址加上申请大小是不是等于第二次申请后返回的地址?

这个正是操作系统防止程序员数组访问越界做出的一些调整。。。操作系统每次会在你申请的内存后面保留些许字节来防止这种危险行为。

下面是一个小小的测试

#include
#include
int main()
{
	int i;
	int *c1 = (int *)malloc(sizeof(int));
	int *c2 = (int *)malloc(sizeof(int));
	*c1 = 123;
	*(c1 + 1) = 456;
	*c2 = 789;
	printf("c1 addr: %p\n", c1);
	printf("c2 addr: %p\n", c2);
	for(i = 0; i < 30; ++i)
	{
		printf("%d ",*(c1 + i));	
	}
	printf("\n");
	return 0;
}

测试结果是

c1 addr: 0xe40010
c2 addr: 0xe40030
123 456 0 0 0 0 33 0 789 0 0 0 0 0 135105 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

c1 和 c2之间隔了32个字节也就是8个整型变量。


有人可能会说我在数组里面定义一个数组,而不是动态分配内存怎么办?

这个确实操作系统在这里不起作用了。

但是别忘了程序是由编译器生成的。

函数里面定义的数组,空间是由栈自动分配,而栈空间分配是依赖于编译器的,因此编译器承担了保护工作。估计设计编译器的人也吃过数组越界的亏,所以道理你懂得。

下面是测试,内容很简单就不说了。

#include
int main()
{
	int a[10] = {0};
	int b[10] = {0};
	int c[10] = {0};
	a[0] = 123, a[10] = 456, a[11] = 789;
	b[0] = 123, b[10] = 456, b[11] = 789;
	c[0] = 123, c[10] = 456, c[11] = 789;
	int i;
	for(i = 0; i < 12; ++i)
		printf("%d ", a[i]);
	printf("\n");
	for(i = 0; i < 12; ++i)
		printf("%d ", b[i]);
	printf("\n");
	for(i = 0; i < 12; ++i)
		printf("%d ", c[i]);
	printf("\n");
	return 0;
}
测试结果:

123 0 0 0 0 0 0 0 0 0 456 789
123 0 0 0 0 0 0 0 0 0 456 789
123 0 0 0 0 0 0 0 0 0 456 789


不同的数据可能之间间隔不同有长有小,所以越个一两个是没问题的。呵呵。

你可能感兴趣的:(个人思考)