内存四区:代码区、全局区、栈区、堆区 代码分析

2023-11-09

阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量。文章设置为仅粉丝可见,是因为写博客确实花了不少精力。希望互相进步谢谢!!


提示:以下是本篇文章正文内容

一、内存四区的总结:

内存四区:代码区、全局区、栈区、堆区

程序执行前,生成代码区、全局区;程序执行后,生成栈区、堆区


1、代码区:

存放CPU的机器指令(即代码的二进制形式)。具有两个特性:共享性和只读性


2、全局区:

全局区的数据在程序结束后才释放。

存放了1、全局变量(函数体外定义的变量) 2、静态变量 (static修饰的变量)3、字符串常量(string类型的常量) + 全局常量(const修饰的全局变量)。**但局部变量和局部常量都不在全局区。 **!!!!!!这里注意常量包括:字符串常量(string类型的常量,例如输出个“hello world”) + 全局常量(const修饰的全局变量) + 局部常量(const修饰的局部变量)

下面代码是对于局部变量、全局变量、静态变量、字符串常量、全局常量、局部常量地址的一个输出,可以观察到全局变量、静态变量、字符串常量、全局常量是在同一段地址,即全局区;而局部变量、局部常量是在另外的同一段地址,即非全局区。

//全局区:全局变量(即函数体外的变量)、静态变量(static修饰的变量)、常量(字符串常量和全局常量【即const修饰的全局变量】)

//不在全局区:局部变量(即函数体内的变量)、局部常量(即const修饰的局部变量)

#include <iostream>
using namespace std;

//创建全局变量
int g_a = 10;
int g_b = 20;

//创建const修饰的全局变量(即全局常量)
const int c_g_a = 10;
const int c_g_b = 20;

int main() {

	//创建局部变量
	int a = 10;
	int b = 20;
	cout << "局部变量a的地址为:" << (int)&a << endl;
	cout << "局部变量b的地址为:" << (int)&b << endl;

	cout << "全局变量g_a的地址为:" << (int)&g_a << endl;
	cout << "全局变量g_b的地址为:" << (int)&g_b << endl;

	//创建静态变量
	static int  s_a = 10;
	static int  s_b = 20;
	cout << "静态变量s_a的地址为:" << (int)&s_a << endl;
	cout << "静态变量s_b的地址为:" << (int)&s_a << endl;

	//常量
	//字符串常量
	cout << "字符串常量的地址为:" << (int)&"hello world" << endl;
	//const修饰的变量(即const常量),包含如下:
	//const修饰的全局变量(即全局常量)
	//const修饰的局部变量(即局部常量)

	cout << "const修饰的全局变量(即全局常量)的地址为:" << (int)&c_g_a << endl;
	cout << "const修饰的全局变量(即全局常量)的地址为:" << (int)&c_g_b << endl;

	//创建const修饰的局部变量(即局部常量)
	const int c_l_a = 10;
	const int c_l_b = 20;

	cout << "const修饰的局部变量(即局部常量)的地址为:" << (int)&c_l_a << endl;
	cout << "const修饰的局部变量(即局部常量)的地址为:" << (int)&c_l_b << endl;

	system("pause");
	return 0;
}

在这里插入图片描述

3、栈区

由编译器自动分配和释放。存放了**函数的参数值、局部变量(函数体内的变量)**等。

注意事项:不要返回局部变量地址。例如有时候想接收局部变量地址,利用指针再输出局部变量值,这时候不会正常输出,因为编译器在执行完函数后就会自动释放局部变量了。下面代码就是对注意事项的解释,可以看看。

//栈区:存放局部变量、函数的参数值等,由编译器自动分配释放
//注意事项:不要返回局部的变量地址      下面代码就是对注意事项的说明
#include <iostream>
using namespace std;

int* func() {

	int a = 10;//局部变量,存放在栈区,函数结束后自动释放
	return &a;//此处返回了局部变量的地址
}

int main() {

	int* p = func();
	//此处实际想两次通过调用函数,返回得到的局部变量地址,实现输出
	cout << *p << endl;    //第一次能成功输出10,因为编译器进行了保留
	cout << *p << endl;    //第二次不能成功输出10,因为编译器不再保留局部变量值

	system("pause");
	return 0;
}

在这里插入图片描述

4、堆区

由程序员分配和释放,若程序员未释放,程序结束时(也就是把exe关掉以后)由操作系统自动回收。c++中主要用new开辟堆区内存,delete释放堆区内存。

下面代码是对于堆区的一个说明,代码跟上面栈区代码很像,也是返回接收了个局部变量地址,但此时用指针就可以正确输出局部变量值,因为程序员并未去释放。重点就是(3)与(4)代码的对比

//栈区:由程序员分配和释放。若程序员未释放,程序结束时由操作系统自动回收
//c++中主要用new开辟堆区
#include <iostream>
using namespace std;

int * func() {
	int * p = new int(10);//利用new把10这个量存放至堆区,再用一个指针去接收这个地址
	return p;
}

int main() {

	int * p = func();
	//三次都能成功输出10,因为程序员并未去释放
	cout << *p << endl;    
	cout << *p << endl;    
	cout << *p << endl;

	system("pause");
	return 0;
}

在这里插入图片描述

若有错误,还望指正哈。


码字不易,谢谢点赞!!!
码字不易,谢谢点赞!!!
码字不易,谢谢点赞!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存四区:代码区、全局区、栈区、堆区 代码分析 的相关文章

  • std::vector 的复制构造函数如何运行?

    一个如何std vector
  • C# 中的 Culture 相当于 Java 中的 Locale 吗?

    C 使用文化的概念 这在操作上与 Java 中的 Locale 类似吗 或者底层概念是否存在显着差异 从文化而不是语言环境的角度进行工作是一种寻找正确抽象层次的尝试 从以类似方式做事的人群的角度来考虑事物 而不是谈论地理区域和语言 并有点疯
  • 简单的 C++ 线程

    我正在尝试在 C Win32 中创建一个线程来运行一个简单的方法 我是 C 线程的新手 但对 C 中的线程非常熟悉 这是我想做的一些伪代码 static void MyMethod int data RunStuff data void R
  • ObservableCollection 上的“Cascade”绑定,包含其他 ObservableCollection

    我有一个项目需要显示合同列表 Class Affaire 每个合约都有一个阶段列表 类别阶段 我使用绑定在 2 个不同的 ListView 中显示它们中的每一个 问题是当我从 ListView 中删除一个 Phase 时 显示 Phases
  • 在 C 中声明和初始化数组

    C 有没有办法先声明然后初始化数组 到目前为止 我一直在初始化一个这样的数组 int myArray SIZE 1 2 3 4 但我需要做这样的事情 int myArray SIZE myArray 1 2 3 4 在 C99 中 您可以使
  • 如何获取任意类型的默认值

    在 C 中我可以写这样的东西 class AnyThing
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 适用于 Windows 的键值数据库?

    除了 MongoDB 和 Memcached 之外 Windows 上还运行哪些键值存储 我见过的大多数似乎只能在 Linux 上运行 Hypertable Redis Lightcloud 相关链接 是否有经过商业验证的云存储 Key g
  • 在标准库中静态链接时如何支持动态插件?

    假设一个应用程序myapp exe是使用构建的g 它使用标志 static libstdc 这样就可以安装在没有环境的情况下libstdc so myapp exe还添加了对某些功能的插件支持plugf可以通过动态加载dlopen来自共享库
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • 复杂的 C 声明

    我刚刚在互联网上浏览了一些代码 发现了这个 float foo SIZE SIZE 我如何阅读这份声明 是否有一套特定的规则来阅读如此复杂的声明 我有一段时间没做这个了 从 开始foo然后向右走 float foo SIZE SIZE fo
  • 带有 Unicode 字符的主机名在 Windows 8 中有效

    Uri CheckHostName 回报UriHostNameType Unknown到处都是 但在 Windows 8 上 它又回来了UriHostNameType Dns 为什么突然间带有 Unicode 西里尔字符的主机名在 Wind
  • 一些涉及类析构函数和删除运算符的内存管理问题?

    在阅读了一些教程后 我仍然不清楚 C 中内存管理的一些观点 1 当使用 new 运算符声明的类超出范围时 是否会调用其析构函数并释放内存 是否有必要调用删除运算符来释放类的内存并调用其析构函数 class Test void newTest
  • C语言:如何获取使用strtok()一次后剩余的字符串

    我的字符串是 A B C D E 分隔符是 如何获取执行 strtok 一次后剩余的字符串 即 B C D E char a A B C D E char separator char b strtok a separator printf
  • 如何最好地为 Visual Studio 2017 构建的 CMake C++ 项目设置输出目录?

    我使用 Visual Studio 2017 使用 vcxproj 文件构建 C 桌面项目 我喜欢默认行为 其中输出目录是项目下面的子目录 例如 myproj sln myproj vcxproj x64 myproj release my
  • 派生类的聚合初始化

    以下代码无法使用 Visual Studio2017 或在线 GDB 进行编译 我期望它能够编译 因为迭代器只是一个具有类型的类 并且它是从公共继承的 这是不允许的还是在 VS2017 中不起作用 template
  • MonoGame 中的 ContentLoadException

    我一直在尝试使用 Xamarin Studio 在 MonoGame 中加载纹理 我的代码设置如下 region Using Statements using System using Microsoft Xna Framework usi
  • 通过 OCI 调用 Oracle 存储过程并使用 C++ 中的 out ref 游标返回结果

    我想使用 OCI 接口从 C 调用 Oracle 存储过程 并使用 out SYS REF CURSOR 作为过程的参数来迭代结果 我是 OCI 新手 所以可能会遗漏一些简单的东西 大部分代码取自这里 我的存储过程是 CREATE OR R
  • 字符串常量之前应有非限定 ID

    我目前正在编写一个 C 应用程序 它与 math h 结合实现了振荡器 我拥有的代码应该可以很好地用于该应用程序 尝试编译目标文件 但是我遇到编译器错误 很可能与语法 等有关 我认为这与命名空间有关 错误 终端输出 User Name Ma
  • Selenium WebDriver 在按钮单击事件上无法正常工作。这里有什么问题呢?

    I am using following code to scrape data from a website I have following interface 这是 HTML div class es content div

随机推荐

  • 清除mac中自动记录的git用户名和密码

    应用程序 实用工具 双击钥匙串 右上角搜索github 右击选项删除
  • 陀螺研究院

    摘要 产业动态 由建行发起的价值30亿美元数字债券将推迟上市 15国正式签署RCEP 全球规模最大自贸协定达成 浙江省首个产业区块链赋能中心落地宁波江北 越南教育和培训部计划在2021年实施区块链技术颁发文凭 深圳市政务区块链专委会正式揭牌
  • pytorch代码实现之SAConv卷积

    SAConv卷积 SAConv卷积模块是一种精度更高 速度更快的 即插即用 卷积 目前很多方法被提出用于降低模型冗余 加速模型推理速度 然而这些方法往往关注于消除不重要的滤波器或构建高效计算单元 反而忽略了特征内部的模式冗余 原文地址 Sp
  • 图像处理(RGB分离)

    图像处理技术 RGB分离 最近学习了图像处理技术 第一个小工程做的事将一张图片的rgb分离 存为三张图片 就像PS中的RGB通道的三张图片一样 我们先准备两张24位真彩色图片 一张宽度像素为4的倍数 一张则不是 我们来看下它的文件头和信息头
  • js文字朗读

    var u new SpeechSynthesisUtterance function read text speed u text text u lang zh u rate speed speechSynthesis speak u
  • 游戏开发安卓知识杂谈系列:关于下载jdk

    想要下载jdk11 去oracle官网下载jdk 发现jdk13以下的版本需要账号登陆 但是去注册账号发现官网账号无法注册 找了半天 网上说Oracle自java SE 8的某个版本以后 需要进行付费才能下载 两个解决办法 找百度网盘或者第
  • webpack使用(5)之处理CSS

    一 需要引入的loader 1 style loader 主要负责创建style标签 并将标签塞入到文档中 2 css loader 主要负责css解析 3 less loader 负责解析less 二 如何引入css资源 1 安装配置st
  • 【数据结构】哈希表

    散列表 也叫哈希表 是根据关键码值而直接进行访问的数据结构 它通过把关键码值映射到表中一个位置来访问记录 以加快查找的速度 哈希表的核心是合适的hash函数 数据范围 解决冲突的办法 这里通过数字分析法设计哈希函数 链地址法解决从冲突 冲突
  • 2023华为OD机试真题【敏感字段加密/字符串风格】【2023.Q2】

    题目描述 给定一个由多个命令字组成的命令字符串 1 字符串长度小于等于127字节 只包含大小写字母 数字 下划线和偶数个双引号 2 命令字之间以一个或多个下划线 进行分割 3 可以通过两个双引号 来标识包含下划线 的命令字或空命令字 仅包含
  • 【机器学习】通俗易懂决策树(实战篇)python实现(为新患者找到合适的药物)

    决策树 我们将学习一种更流行的机器学习算法 决策树 我们将使用此算法从患者的历史数据以及他们对不同药物的反应大数据中 用训练过的决策树来构建分类模型预测未知患者的类别 或者说为新患者找到合适的药物 导入以下包 numpy as np pan
  • docker快速学习--容器的数据卷--04

    一 数据卷概念 数据卷是宿主机中的一个目录或文件 当容器目录和数据卷目录绑定后 对方的修改会立即同步 一个数据卷可以被多个容器同时挂载 一个容器也可以被挂载多个数据卷 二 数据卷作用 容器数据持久化 外部机器和容器间接通信 数据交互 容器之
  • python进阶--正则表达式(2)

    一 初识正则表达式 为了使计算机具有在文本中检索某种模式的能力 我们引入了正则表达式 正则表达式为高级的文本模式匹配 抽取或者文本形式的搜素和替换功能提供了基础 利用正则表达式能够匹配多个字符串 正则表达式的强大之处在于引入了特殊字符来定义
  • ajax工作原理 前后端交互流程

    一 前后端交互流程 1 服务器 提供某种服务器的机器 计算机 qq音乐 音频服务器 迅雷 文件服务器 qq邮箱 邮件服务器 爱奇艺 视频服务器 谷歌 web服务器 2 前端 访问 服务器的四种方式 1 直接在地址栏输入网址 网页会跳转 全局
  • Java Servlet 简单的登录代码

    需要的jar包 commons beanutils 1 8 0 jar druid 1 0 9 jar spring jdbc 5 0 0 RELEASE jar spring beans 5 0 0 RELEASE jar mysql c
  • C++(19)——智能指针shared_ptr

    shared ptr的概念 shared ptr实现共享式拥有 shared ownership 概念 多个智能指针可以指向相同对象 该对象和其相关资源会在 最后一个引用 reference 被销毁 时候释放 基本原理 智能指针是 几乎总是
  • MySQL数据库学习——SQL分类——DDL

    不能重复创建 可以用if not exists来避免这种情况 比如我要创建一个test的数据库 用if not exists系统就会创建 删除guzifenshisb这个数据库 使用数据库和查询数据库
  • Basic Level 1083 是否存在相等的差 (20分)

    题目 给定 N 张卡片 正面分别写上 1 2 N 然后全部翻面 洗牌 在背面分别写上 1 2 N 将每张牌的正反两面数字相减 大减小 得到 N 个非负差值 其中是否存在相等的差 输入格式 输入第一行给出一个正整数 N 2 N 10 000
  • protobuf

    https www jianshu com p 4b987ef826d3
  • 【前端部署】多个vue项目部署到Linux服务器

    前端部署 多个vue项目部署到Linux服务器 文章目录 前端部署 多个vue项目部署到Linux服务器 前言 一 修改vue项目中配置 1 修改vue config js 2 修改router文件下的index js 3 打包项目 二 修
  • 内存四区:代码区、全局区、栈区、堆区 代码分析

    阅读前请看一下 我是一个热衷于记录的人 每次写博客会反复研读 尽量不断提升博客质量 文章设置为仅粉丝可见 是因为写博客确实花了不少精力 希望互相进步谢谢 文章目录 阅读前请看一下 我是一个热衷于记录的人 每次写博客会反复研读 尽量不断提升博