二维数组内存布局疑问:是否以连续一维数组实现?越界访问合法吗?
二维数组内存布局与越界访问的问题解析
1. 二维数组的内存布局
在C语言中,像int a[3][4]这类二维数组,内存是完全连续的,本质就是以一维数组的形式实现的。它的元素会按行优先顺序依次存放:第一行的1,2,3,4先占据4个int的内存空间,紧接着是第二行的5,6,7,8,最后是第三行的9,10,11,12,整个数组在内存中是一块没有间隙的连续区域。
2. 为什么a[0][6]和a[1][2]输出相同
C语言的数组下标访问本质是指针偏移计算。对于二维数组a[i][j],编译器会自动将其转换为*(a + i * 每行元素数 + j)的形式(这里每行有4个int)。
- 计算
a[0][6]:a + 0*4 +6 = a+6,指向数组中第7个元素(从0开始计数),也就是值7。 - 计算
a[1][2]:a +1*4 +2 = a+6,同样指向第7个元素。
所以两者访问的是同一块内存地址,输出自然都是7。
3. 该操作是否合法?
绝对不合法。a[0]是一个长度为4的一维数组,访问a[0][6]属于明确的数组下标越界,这在C标准中属于未定义行为。
未定义行为意味着编译器不对这种操作的结果做任何保证——这次运行可能输出预期值,但换个编译器、开启优化选项或改变代码上下文后,可能出现崩溃、数据篡改、输出随机值等各种不可预料的情况。这种写法完全不能出现在生产代码中,也绝不能依赖它的“偶然正确”结果。
内容的提问来源于stack exchange,提问作者TH讠NK
相关产品推荐
相关产品推荐

