当前位置: 首页 > java >正文

C++内存模型

C++内存模型

计算机程序内存模型

高地址

栈 (Stack)← 局部变量、函数参数、返回地址(自动分配、函数退出时自动释放)
内存映射区← 动态库映射、mmap 分配的内存
堆 (Heap)← new / malloc 分配(需要手动释放)
BSS 段← 未初始化的全局/静态变量 int g1; // 放 BSS
数据段 (Data)← 已初始化的全局/静态变量 int g2=10; // 放 Data
代码段 (Text)← 程序的机器指令,常量字符串 const char* s = “abc”;

低地址

然后翻译自cpp官方网站的内存模型介绍:
内存模型为 C++ 抽象机器定义了计算机内存存储语义。
C++ 程序可用的内存是一个或多个连续的字节序列。每个字节有自己独有的内存地址。
字节(Byte)
字节是内存中的最小可寻址单元,由连续的多个比特组成。C++ 中,char/unsigned char/signed char 的对象存储和值表示均使用恰好 1 字节。于是,字节中有多少比特,可以通过 std::numeric_limits::digits取得。

内存位置(Memory Location)
内存位置是标量类型(算数类型、指针类型、枚举类型或是 std::nullptr_t)的对象;或是,长度不为零的位域组成的最长连续序列。

struct S {char a;     // memory location #1int b : 5;  // memory location #2int c : 11, // memory location #2 (continued): 0,  // zero-length, 强制对齐到下一个int边界d : 8;  // memory location #3struct {int ee : 8; // memory location #4} e;
} obj; // The object 'obj' consists of 4 separate memory locations

这段代码在32位机器上的内存分布是:

Offset  内容
0x00    a (1 byte)
0x01    padding (3 bytes)
0x04    b:5, c:11, unused:16
0x08    d:8, unused:24
0x0C    e.ee:8, unused:24

所以为了节省空间,可以采用以下措施:

  • 同类型放一起 → 减少不同类型对齐带来的空洞
  • 大类型放前,小类型放后 → 利用剩余空间
  • 位域合理使用 → 多个位域尽量放同一个存储单元
  • 对齐指令 / pragma → 可以压缩结构体,但可能牺牲性能

注意:语言中的许多特性会引入额外的内存位置。这些内存位置程序无法访问,而是为编译器实现自行管理。这些特性例如:引用和虚函数。

大小端访问问题

假设我们有一个 32-bit 整数:

uint32_t x = 0x12345678; // 十六进制表示

小端存储(Intel x86 常见)

内存地址从低到高依次存储:

地址: 0x1000  0x1001  0x1002  0x1003
内容: 0x78    0x56    0x34    0x12

低地址存最低有效字节(0x78),高地址存最高有效字节(0x12)。

大端存储(某些 ARM 或网络协议)

内存地址从低到高依次存储:

地址: 0x1000 0x1001 0x1002 0x1003
内容: 0x12 0x34 0x56 0x78

低地址存最高有效字节(0x12),高地址存最低有效字节(0x78)。

32 位机器的影响

内存访问:如果 CPU 是小端,访问 (uint16_t)(&x) 取低 16 位 → 0x5678

网络传输:网络协议一般使用大端(Network Byte Order)

在小端机器上需要 htonl/ntohl 转换
**注意:**这里两位两位的读取存储,只是因为0X情况下是16位存储,也就是一个数字是2个字节(16位),当32位存储读取的时候,肯定是4个字节,也就是32位,所以会两个两个的存储读取;另外大小端是规定了存储读取的顺序,所以其实当读取出来的时候会自动根据大小端的定义重新排列数据。

http://www.xdnf.cn/news/18086.html

相关文章:

  • 数据结构代码分享-1 顺序表
  • Redis面试精讲 Day 23:Redis与数据库数据一致性保障
  • Python 设计模式详解 —— 掌握软件设计的通用解决方案
  • 常用的SQL语句
  • ReactNode 类型
  • Java学习笔记:IDEA简单使用技巧
  • 使用vscode的task.json来自动执行make命令,而不直接使用终端
  • Eclipse Tomcat Configuration
  • 基于Python的旅游推荐系统 Python+Django+Vue.js
  • 【抽象类和接口】
  • Javascript面试题及详细答案150道之(106-120)
  • HAL-USART配置
  • 数据电台询价的询价要求
  • 计算机毕业设计java的小天鹅酒店月子会所管理小天鹅酒店母婴护理中心管理系统设计小天鹅酒店产后护理会所信息化管理平台
  • 利用pyxlsbwriter包实现写入xlsb和xlsx格式及读取效率的比较
  • Forward Propagation|前向传播
  • Python可视化工具-Bokeh:动态显示数据
  • 功能强大!开源免费的视频翻译、音视频转录工具
  • 深度解析 Tomcat ProtocolHandler 工作原理
  • 牛客周赛 Round 104(小红的矩阵不动点/小红的不动点权值)
  • 【AI智能体】Dify 搭建发票识别助手操作实战详解
  • 深入理解QFlags:Qt中的位标志管理工具
  • 【URP】[法线贴图]为什么主要是蓝色的?
  • PowerPoint和WPS演示让多个对象通过动画同时出现
  • LeetCode 刷题【44. 通配符匹配】
  • 【杂谈】-以质代量:谷歌主动学习范式重构AI训练逻辑
  • 朝花夕拾(四) --------python中的os库全指南
  • 【k8s】Kubernetes核心概念与架构详解
  • 向量数据库
  • Qt | 四种方式实现多线程导出数据功能