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所示.四级页表分 ...
随机推荐
- 网课党的双重大福利!Github学生账号和Educative合作,总共2000美金的课程免费半年啦
如果你在北美计算机求职,各种算法培训课对你肯定不陌生.其中有一门课叫做System Design的课,更是人人皆知. 系统设计传送门: Grokking the System Design Inter ...
- python基础操作以及变量运用
今天学习关于pycharm的操作以及变量的知识 1.关于pycharm的基本操作,作为一个小白,仪式感还是要有 在基础界面上新建然后打印hello world,也是对python的一种尊重吧 2.关于 ...
- WIN10升级后输入法无法输入中文
查看是否安装了中文输入法,可能在升级后用户文件出现问题. 在设置>语言.添加一下中文输入法.
- 如何实施DevOps
对于长期在孤立的架构下工作的组织来说,转移到协作式DevOps系统似乎是难以成功的.为了进一步提高效率,必须改变观念,并进行团队文化改变.例如:许多人认为只有自动化工具才能解决DevOps,其实这是不 ...
- Maven 基础环境搭建 项目依赖jar包导入
一.创建一个Maven工程 不清楚的话请查阅其它文档. 二.引入项目依赖的jar包 1.Spring 2.SpringMvc 3.Mybatis 4. 数据库连接池,驱动 5.其它(jstl.serv ...
- $.fn.serializeObject对为disabled属性的失效
问题现象: 在查生产tomcat下的localhost日志时,发现今天的记录有不少次都报org.apache.ibatis.exceptions.TooManyResultsException: Ex ...
- 毒瘤养成记1: 如何卡hash
各位毒瘤大家好, 最近模拟赛考了一道trie+主席树好题, 但大家都用hash水过了这道题(包括我), 为了测试一下新搭建的HEAT OJ的hack功能, 我将继续扮演毒瘤的角色, 用毒瘤的艺术形象努 ...
- 安装xpath helper
1.下载 版本是:2.02的 链接:https://pan.baidu.com/s/1YdyTbWElL904EMQ-9Ougnw 提取码:bxxa 2.无效安装的解决方案 参考链接:https:// ...
- [bzoj1875] [洛谷P2151] [SDOI2009] HH去散步
Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又 ...
- 【JDK1.8】 Java小白的源码学习系列:HashMap
目录 Java小白的源码学习系列:HashMap 官方文档解读 基本数据结构 基本源码解读 基本成员变量 构造器 巧妙的tableSizeFor put方法 巧妙的hash方法 JDK1.8的putV ...