c++ 内存分配中一个有趣的小问题

以下代码测试环境: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个区,分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

扫描二维码关注公众号,回复: 7711959 查看本文章

:堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。

:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

自由存储区:自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。

全局/静态存储区:这块内存是在程序编译的时候就已经分配好的,在程序整个运行期间都存在。例如全局变量,静态变量。

常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。

上面的问题涉及到两个区:全局/静态存储区。

因此我有个不成熟的推测:

栈的空间是系统预定分配好的,假如我定义了int arr[5],那么系统就一定给我5*4(32位系统下)个字节的空间,系统不允许我访问超过这个空间的地址上的数据。

而全局/静态存储区则不同,当我定义int arr[5]时,系统给我返回arr的首地址,我不仅可以根据这个首地址去访问20个字节的内容,还可以访问这二十个字节以外的内容。

猜你喜欢

转载自www.cnblogs.com/XiaoXiaoShuai-/p/11778558.html