以下代码测试环境:vs2019
执行这么一段代码,看看会发生什么。
1 int main() 2 { 3 int arr[5] = { 0 }; 4 arr[5] = 1; 5 }
毫无疑问,会报错,因为访问越界了。
再看看另一段代码
1 int arr[5] = { 0 }; 2 int main() 3 { 4 arr[5] = 1; 5 }
与上面的代码相比几乎没什么差别,仅仅把arr的定义和初始化搬到了函数外面,但执行程序却没有出错。
类似的还有这么一段代码:
1 int main() 2 { 3 static int arr[5] = { 0 }; 4 arr[5] = 1; 5 }
同样也能执行成功,那么这是为什么呢?
探究:
我们知道(以下这段话摘自https://blog.csdn.net/u010183728/article/details/81629706)
在C++中内存分为5个区,分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
堆:堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。
栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
自由存储区:自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。
全局/静态存储区:这块内存是在程序编译的时候就已经分配好的,在程序整个运行期间都存在。例如全局变量,静态变量。
常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。
上面的问题涉及到两个区:栈和全局/静态存储区。
因此我有个不成熟的推测:
栈的空间是系统预定分配好的,假如我定义了int arr[5],那么系统就一定给我5*4(32位系统下)个字节的空间,系统不允许我访问超过这个空间的地址上的数据。
而全局/静态存储区则不同,当我定义int arr[5]时,系统给我返回arr的首地址,我不仅可以根据这个首地址去访问20个字节的内容,还可以访问这二十个字节以外的内容。
原文:https://www.cnblogs.com/XiaoXiaoShuai-/p/11778558.html