c++ 内存分配中一个有趣的小问题
[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++ 内存分配中一个有趣的小问题的更多相关文章
- 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型
小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...
- 一个有趣的小例子,带你入门协程模块-asyncio
一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...
- 单片机内存分配中的.text .data .bss heap stack
[本文转自:http://www.51hei.com/bbs/dpj-41696-1.html] .text段:代码段(code segment/text segment)通常是指用来存放程序执行代码 ...
- dubbo debug过程中一个有趣的问题
最近在debug dubbo代码过程中遇到的很有趣的问题 我们都知道dubbo ReferenceBean是消费者的spring bean包装,为了查一个consumer端的问题,在Reference ...
- 解析 Java 反射题中一个有趣的坑
public class Test { public void age(int age) { System.out.println("int age="+age); } publi ...
- Spring框架中一个有用的小组件:Spring Retry
1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spri ...
- Linux内核中常见内存分配函数(一)
linux内核中采 用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系 统中,用到了四级页表. * 页全局目录(Page Global Dir ...
- Linux内核中常见内存分配函数【转】
转自:http://blog.csdn.net/wzhwho/article/details/4996510 1. 原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页 ...
- Linux内核中常见内存分配函数
1. 原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...
随机推荐
- 从操作系统层面理解Linux下的网络IO模型
I/O( INPUT OUTPUT),包括文件I/O.网络I/O. 计算机世界里的速度鄙视: 内存读数据:纳秒级别. 千兆网卡读数据:微妙级别.1微秒=1000纳秒,网卡比内存慢了千倍. 磁盘读数据: ...
- C#调用7z实现文件的压缩与解压
1.关于7z 首先在这里先介绍一下7z压缩软件,7z是一种主流的 压缩格式,它拥有极高的压缩比.在计算机科学中,7z是一种可以使用多种压缩算法进行数据压缩的档案格式.主要有以下特点: 来源且模块化的组 ...
- 简单的c语言程序
我猜大部分人第一门掌握的语言是c语言吧(我第一门学的是python). 在接下来的文章里我会逐步的介绍有关自己对c语言的理解,希望对一些小伙伴有帮助,有哪里有错误希望大佬指出. 首先这是第一个c语言程 ...
- Java设计模式之三种工厂模式
工厂模式实现了创建者和调用者的分离,实现了更好的解耦. 详细分类: 1) 简单工厂模式(静态工厂模式): 2) 工厂方法模式: 3) 抽象工厂模式 面向对象设计的基本原则: 1) OC ...
- SVN打patch,某Java文件提示svn:mime-type = application/octet-stream的问题
在使用SVN合版本时发现某文件有冲突,正常冲突文件是可以编辑修改的,但是该文件无法编辑,我只好选择后续修改选项,问题好诡异啊!!!在解决完其他冲突后,我选择了在eclipse开发工具内将修改的代码调整 ...
- LeetCode 第17题--电话号码的组合(DFS)
1. 题目 2.题目分析与思路 3.代码 1. 题目 输入:"23" 输出:["ad", "ae", "af", &qu ...
- Flash 上下文管理
1.Local() 作用:为每个协程或线程创建一个独立的内存空间 储存格式: { 唯一标识: {'stack': []} } 代码 try: from greenlet import getcurre ...
- CTF-Keylead(ASIS CTF 2015)
将keylead下载到本地用7-ZIP打开,发现主要文件 keylead~ 在ubuntu里跑起来,发现是个游戏,按回车后要摇出3,1,3,3,7就能获得flag. 拖进IDA 直接开启远程调试,跑起 ...
- BZOJ 2648 世界树
题目传送门 分析: 喜 闻 乐 见 的虚树 但是建好虚树后的DP也非常的恶心 我们先考虑每个关键点的归哪个点管 先DFS一次计算儿子节点归属父亲 再DFS一次计算父亲节点归属儿子 然后然后我们对于虚树 ...
- SpringBoot配置嵌入式Servlet容器
1).如何定制和修改Servlet容器的相关配置: 1.修改和server有关的配置(ServerProperties[也是EmbeddedServletContainerCustomizer]): ...