C++内存分配中一个有趣的小问题(原来博客园已经发布的文章不能重新用markdown来写呀)

以下代码测试环境:vs2019

问题的提出

执行这么一段代码,看看会发生什么:

int main()
{
        int arr[5] = { 0 };
	arr[5] = 1;
}

毫无疑问,会报错,因为访问越界了。


再看看另一段代码:

int arr[5] = { 0 };
int main()
{
    arr[5] = 1;
}

与上面的代码相比几乎没什么差别,仅仅把arr的定义和初始化搬到了函数外面,但执行程序却没有出错。

类似的还有这么一段代码:

int main()
{
    static int arr[5] = { 0 };
    arr[5] = 1;
}

同样也能执行成功,那么这是为什么呢?


问题的探索

以下这段话摘自

C++中内存分为5个区,分别是自由存储区全局/静态存储区常量存储区
是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。
:在执行函数时,函数内局部变量的存储单元都可以在上创建,函数执行结束时这些存储单元自动被释放。内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
自由存储区自由存储区C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区
全局/静态存储区:这块内存是在程序编译的时候就已经分配好的,在程序整个运行期间都存在。例如全局变量静态变量
常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。

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


个人的推测

基于以上结果,我有个不成熟的小推测:

  • 的空间是系统预定分配好的,假如我定义了int arr[5],那么系统就一定给我5*4(32位系统下)个字节的空间,系统不允许我访问超过这个空间的地址上的数据。
  • 全局/静态存储区则不同,当我定义int arr[5]时,系统给我返回arr首地址,我不仅可以根据这个首地址去访问20个字节的内容,还可以访问这二十个字节以外的内容。
posted @ 2020-03-10 00:26  机智的小小帅  阅读(181)  评论(0编辑  收藏  举报