[TOC]

以下代码测试环境:**vs2019**

## 问题的提出
执行这么一段代码,看看会发生什么:

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

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

***
再看看另一段代码:

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

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

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

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

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

***

## 问题的探索
[以下这段话摘自](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个字节的内容,还可以访问这二十个字节以外的内容。

c++ 内存分配中一个有趣的小问题的更多相关文章

  1. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

  2. 一个有趣的小例子,带你入门协程模块-asyncio

    一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...

  3. 单片机内存分配中的.text .data .bss heap stack

    [本文转自:http://www.51hei.com/bbs/dpj-41696-1.html] .text段:代码段(code segment/text segment)通常是指用来存放程序执行代码 ...

  4. dubbo debug过程中一个有趣的问题

    最近在debug dubbo代码过程中遇到的很有趣的问题 我们都知道dubbo ReferenceBean是消费者的spring bean包装,为了查一个consumer端的问题,在Reference ...

  5. 解析 Java 反射题中一个有趣的坑

    public class Test { public void age(int age) { System.out.println("int age="+age); } publi ...

  6. Spring框架中一个有用的小组件:Spring Retry

    1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spri ...

  7. Linux内核中常见内存分配函数(一)

    linux内核中采 用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系 统中,用到了四级页表. * 页全局目录(Page Global Dir ...

  8. Linux内核中常见内存分配函数【转】

    转自:http://blog.csdn.net/wzhwho/article/details/4996510 1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页 ...

  9. Linux内核中常见内存分配函数

    1.      原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...

随机推荐

  1. DFT与IDFT

    [转]https://blog.csdn.net/mingzhuo_126/article/details/88044390 二.编程实现考滤到DFT和IDFT算法过程中有部分相似,可以把它们合成到一 ...

  2. Vue.js 入门 --- vue.js 安装

    本博文转载  https://blog.csdn.net/m0_37479246/article/details/78836686 Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据 ...

  3. HashMap 源码赏析 JDK8

    一.简介 HashMap源码看过无数遍了,但是总是忘,好记性不如烂笔头. 本文HashMap源码基于JDK8. 文章将全面介绍HashMap的源码及HashMap存在的诸多问题. 开局一张图,先来看看 ...

  4. 单调队列优化 dp

    The only difference between easy and hard versions is the constraints. Vova likes pictures with kitt ...

  5. 不止开源,不止跨平台。微软的 .NET Core 还有哪些强大之处值得我们学习?

    自从 2016 年微软发布了 .NET Core 1.0,至今 4 年的时间里,.NET Core 历经 7 个正式版本和几十个 Preview 版本..NET Core 作为最通用的框架,和其他软件 ...

  6. Java.Json模板.省市区三级JSON

    [ { "name": "北京市", "city": [ { "name": "北京市", &quo ...

  7. 网站 cache control 最佳实践

    推荐阅读: 2020年软件开发趋势 高并发案例 - 库存超发问题 负载均衡的分类及算法 异地多活架构 Postman 的替代品来了 有时,当第二次访问网站时,看起来比较怪,样式不正常. 通常,是因为 ...

  8. Java程序员学习Go语言—之一

    转载:https://www.luozhiyun.com/archives/206 GOPATH 工作空间 GOPATH简单理解成Go语言的工作目录,它的值是一个目录的路径,也可以是多个目录路径,每个 ...

  9. [ZJOI2006]书架(权值splay)

    [ZJOI2006]书架(luogu) Description 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看 ...

  10. [HNOI2008]Cards(dp,Burnside引理)

    Burnside引理: 参考自 某大佬对Burnside引理和Polya定理的讲解 相关概念 群:在数学中,群表示一个拥有满足封闭性.满足结合律.有单位元.有逆元的二元运算的代数结构. 置换群:由有限 ...