[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. JWT (一):认识 JSON Web Token

    JWT(一):认识 JSON WebToken JWT(二):使用 Java 实现 JWT 什么是 JWT? JSON Web Token(JWT)是一种开放标准(RFC 7519),它定义了一种紧凑 ...

  2. 【转】DB2数据库编目的概念以及对其的正确解析

    此文章主要向大家描述的是DB2数据库编目的概念以及对DB2数据库编目的概念的正确理解,在DB2中编目(catalog)这个单词看似很难理解,我自己当初在学习DB2数据库的时候也常常被这个编目搞的很不明 ...

  3. Java操作Jxl实现数据交互。三部曲——《第三篇》

    Java操作Jxl实现上传文本文件实现转PDF格式在线预览. 本文实现背景Web项目:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:S ...

  4. dubbo配置文件解读(1)

    详细的Dubbo配置也可以参考:https://blog.csdn.net/abcde474524573/article/details/53026110 (1)<dubbo:service/& ...

  5. Python思维导图(一)—— 基础

    前言 思维导图并不能涵盖所有知识点,只是梳理某个知识点下我们需要重点关注的分支:根据自己的情况可以进行拓展学习 计算机基础 博主认为需要重点掌握的有 编译型语言和解释型语言的区别?分别有什么编程语言? ...

  6. springboot集成restdocs输出接口文档

    1.pom文件新增restdocs <dependency>    <groupId>org.springframework.restdocs</groupId> ...

  7. python3文件操作

    文件操作的过程 1)打开 2)操作 3)关闭 1.写(清空写入) # f = open(file='test', mode='w', encoding='utf-8') # 第一种情况 # f.wri ...

  8. double涉及大数据的时候会变成科学计数法

    double b=1.23456789128E8DecimalFormat df = new DecimalFormat("0.00");//精度自己控制保留几位小数点 Strin ...

  9. 【数据结构】FHQ Treap详解

    FHQ Treap是什么? FHQ Treap,又名无旋Treap,是一种不需要旋转的平衡树,是范浩强基于Treap发明的.FHQ Treap具有代码短,易理解,速度快的优点.(当然跟红黑树比一下就是 ...

  10. Tomcat 9 与JDK 8 的安装与配置

    Tomcat 9的安装与配置 解压压缩包,我的解压路径是:D:\Program Files\Java 注意:这里tomcat压缩包不能解压到C盘,否则会因为C盘文件夹访问权限授权问题,没法解决后面出现 ...