C++ 中内存分区总结

2023-11-12

背景

C++ 中最基本的存储单位是字节,C++ 中所有的数据都是由对象组成的,每一个对象都包含了一个或多个内存位置。
C++ 中有多种不同类型的内存区域,不同区域存放不同的数据,赋予数据不同的生命周期。
程序在执行时将供用户使用内存大致划分为以下区域:常量数据区、全局/静态数据区、栈区、堆区、自由存储、代码区。

常量数据区

①.常量数据区主要用于存储字符串常量或者其他在编译期就已经知道的数据。

②.常量数据区中的数据在整个程序的生命周期中都有效。

③.常量数据区中的数据在程序结束后由操作系统进行释放。

④.常量数据区中的数据是只读的。

全局/静态数据区

①.全局/静态数据区主要用于存放全局变量和静态变量。
②.在程序启动时,全局/静态数据已经分配了存储空间。
③.全局/静态数据区中的数据在程序结束后由操作系统释放。
④.未初始化的静态变量会被程序自动初始化为 0,静态局部变量在程序执行到该对象的声明处时被首次初始化。

栈区

①.栈区用于存放函数的参数,局部变量、返回值等。
②.栈区的数据由编译器自动进行分配,在作用域内有效。
③.在超出变量作用域后,栈中数据由编译器自动释放。
④.栈内存分配运算内置于处理器的指令集,效率高、但是分配的内存容量有限。

自由存储

①.自由存储是动态内存区域,通过 new/delete 来分配和释放。
②.分配空间时,编译器根据指定类型自动分配空间大小,并调用构造函数进行初始化。
③.释放空间时,编译器会调用析构函数,并回收内存空间。
④.new 和 delete 必须配套使用。

堆区

①.堆是动态内存区域,通过 malloc/free 来分配和释放。
②.分配空间时,需要显示指定空间大小,不会调用构造函数。
③.释放空间时,编译器不会调用析构函数,只是释放内存空间。
④.malloc和 free 必须配套使用。

代码示例

#include "iostream"
#include <iomanip>

using namespace std;

constexpr int c_a = 10;
const int c_b = 2;

int g_a = 10;
static int s_g_b = 10;

int main()
{
	static int s_l_c = 0;

	int l_a = 2;
	const int l_c_b = 3;
	constexpr int l_c_c = 10;

	int * p_a = new int(10);
	void * p_b = malloc(sizeof(int));

	cout << "=========常量数据区======" << endl;
	cout <<setw(30) << left << "字符串常量 hello 地址:"<< static_cast<const void*>("hello") << endl;
	cout <<setw(30) << left << "常量表达式 c_a 地址:" << &c_a << endl;
	cout << setw(30) << left << "全局常量 c_b 地址:" << &c_b << endl;
	cout << "=========全局数据区======" << endl;
	cout << setw(30) << left << "全局变量 g_a 地址:" << &g_a << endl;
	cout << setw(30) << left << "静态全局变量 s_g_b 地址:" << &s_g_b << endl;
	cout << setw(30) << left << "静态局部变量 s_l_c 地址:" << &s_l_c << endl;
	cout << "=========栈区======" << endl;
	cout << setw(30) << left << "局部变量 l_a 地址:" << &l_a << endl;
	cout << setw(30) << left << "局部常量 l_c_b 地址:" << &l_c_b << endl;
	cout << setw(30) << left << "局部常量表达式 l_c_c 地址:" << &l_c_c << endl;
	cout << "=========自由存储======" << endl;
	cout << setw(30) << left << "指针 p_a 指向地址:" << p_a << endl;
	cout << "=========堆区======" << endl;
	cout << setw(30) << left << "指针 p_b 指向地址:" << p_b << endl;
	cout << "=========代码区======" << endl;
	cout << setw(30) << left << "main 函数地址:" << main << endl;

	system("pause");
    return 0;
}

运行结果如下:
在这里插入图片描述

在这里插入图片描述

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

C++ 中内存分区总结 的相关文章

  • 如何获取正在访问 ASP.NET 应用程序的当前用户?

    为了获取系统中当前登录的用户 我使用以下代码 string opl System Security Principal WindowsIdentity GetCurrent Name ToString 我正在开发一个 ASP NET 应用程
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐