C语言-------数组越界的问题

问题

定义一个数组array[5],那么数组包含了array[0],array[1],array[2],array[3],array[4],那array[5],array[6]…会是什么呢?
很多书里面都会说array[5]会出现下标越界的错误,没错这确实是越界了,但实际上编译器并不会给你报错。

下面来看一段代码

#include <stdio.h>

void showArray(int *array, int arrayLenth)
{
	for (int i = 0; i < arrayLenth; i++)
	{
		printf("address:%#x, array[%d]:%d\n", array + i, i, array[i]);
	}
	printf("\n");
}

int main()
{
	int k = -6;
	int array[5] = {0, 1, 2, 3, 4};
	int j = -520;

	printf("address:%#x, j:%d\n", &j, j);
	printf("address:%#x, array[%d]:%d\n", array - 1, -1, array[-1]);
	showArray(array, 5);
	printf("address:%#x, array[%d]:%d\n", array + 5, 5, array[5]);
	printf("address:%#x, array[%d]:%d\n", array + 6, 6, array[6]);
	printf("address:%#x, array[%d]:%d\n", array + 7, 7, array[7]);

	printf("address:%#x, k:%d\n", &k, k);
	
	return 0;
}

使用的是windows gcc编译器

address:0xe37ff9ec, j:-520
address:0xe37ff9ec, array[-1]:-520
address:0xe37ff9f0, array[0]:0
address:0xe37ff9f4, array[1]:1
address:0xe37ff9f8, array[2]:2
address:0xe37ff9fc, array[3]:3
address:0xe37ffa00, array[4]:4

address:0xe37ffa04, array[5]:359
address:0xe37ffa08, array[6]:16
address:0xe37ffa0c, array[7]:-6
address:0xe37ffa0c, k:-6

画出内存分布图
在这里插入图片描述

同样的代码使用linux gcc编译器编译

address:0xa8c76a5c, j:-520
address:0xa8c76a5c, array[-1]:-520
address:0xa8c76a60, array[0]:0
address:0xa8c76a64, array[1]:1
address:0xa8c76a68, array[2]:2
address:0xa8c76a6c, array[3]:3
address:0xa8c76a70, array[4]:4

address:0xa8c76a74, array[5]:32764
address:0xa8c76a78, array[6]:348207360
address:0xa8c76a7c, array[7]:901600418
address:0xa8c76a58, k:-6

画出内存分布图
在这里插入图片描述

结论

很明显可以看出越界后的array[5],array[6]。。。是取到了什么值,有可能是随机值,也有可能是越界访问到定义array数组上下文的变量。而且不同操作系统的编译器还有差异。
那为什么定义了array[5],array[5]编译器不会报错呢,因为[]这个本质是解引用,什么意思,即array[5] = *(array+5)=*(&(array[5])), 中括号里面的值是基于类型的偏移量,而array则是array[0]的地址,也即数组array[5]的首地址。访问一个地址是一个非常正常的操作,编译器自然不会报错,当然如果你访问了一个不可访问的地址,那编译器确实是会报错误的。
所以数组越界的写法本身没有错,但是注意这样的写法是不规范的,会对他人造成误解,且也没有必要这样写。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值