[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. 天梯 L2 树的遍历(已知后序中序求层序)

    树的遍历 (25 分) 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤30),是二叉树中结点的个数.第二行 ...

  2. OpenJ_Bailian 4103 踩方格(搜索 动态规划 )

    题目传送门OpenJ_Bailian 4103 描述 有一个方格矩阵,矩阵边界在无穷远处.我们做如下假设:a.    每走一步时,只能从当前方格移动一格,走到某个相邻的方格上:b.    走过的格子立 ...

  3. 【转】最简单的安装pip的方法

    网上有各种方法安装pip,针对不同的系统方法还不一样,最后发现还是下面这种方法最简单,直接了当干脆方便,适用于Windows和Linux. (1)下载pip 进入https://pypi.python ...

  4. ArcGIS Server for JavaScript 3.3 的安装部署

    一.安装包下载 首先从官网下载ArcGIS API for JavaScript 3.3 的API和SDK,地址:http://support.esrichina.com.cn/2011/0223/9 ...

  5. Java控制台五子棋(纯算法)

    Java五子棋小游戏 本方案是基于控制台写的一个代码 没有花里胡哨的界面,只为研究算法 仅仅用了200行代码 下面是的是运行结果 游戏运行结果 这里我就很简单的复制了一个结果 第9回合,下子方:玩家2 ...

  6. 揭发233的docker/machine

    继手动滑稽之golang-vmware-driver广告篇,今天把vmware-driver完成 然而我却要发一篇牢骚,这是对docker公信力的挑战!!! 本来很简单的升级到vmware 15.x的 ...

  7. docker使用阿里云加速器

    1 登录阿里云获得地址 登录https://cr.console.aliyun.com ,点击"镜像加速器",会给我一个地址. 2 写入/etc/docker/daemon.jso ...

  8. crawler 听课笔记 碎碎念 2 一些爬虫须知的基本常识和流程

    html的宗旨:      <标签 属性=”属性的值“></标签>        只是对于文本的一种解释划分吧 dom的宗旨:      就是一个大数组,处理方便,效率低 xm ...

  9. Java入门 - 语言基础 - 19.方法

    原文地址:http://www.work100.net/training/java-method.html 更多教程:光束云 - 免费课程 方法 序号 文内章节 视频 1 概述 2 方法的定义 3 方 ...

  10. 安装mysql遇到的问题

    想在自己的PC上安装mysql服务器,首先在官网下载mysql的安装文件. MySQL安装文件分两种 .msi和.zip ,.msi需要安装,.zip文件需要配置环境变量. 我首先下载的是不需要安装的 ...