IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言struct为什么要内存对齐 -> 正文阅读

[C++知识库]C语言struct为什么要内存对齐

C语言中的struct会做内存对齐,这个已经是被广为人知的,但是网上对于内存对齐的原因的解释却比较少,很多资料仅仅是说为了“提高读写效率",这个理由其实还是很难有说服力。

这里提供一个新的解释思路,就是我们要知道struct是可以直接做赋值的,利用=符号可以直接做深拷贝。

typedef struct Foo Foo;
struct Foo {
  int a;
  short b;
  char c;
};

int main () {
  Foo X = {1, 2, 'a'};
  Foo Y = X;
  Y.c = 'c';
  printf("X.c = %c, Y.c = %c\n", X.c, Y.c);
  // X.c = a, Y.c = c
  return 0;
}

然后我们来思考一下,这个深拷贝怎么去实现。

如果有内存对齐:

这个struct Foo,根据内存对齐的知识,我们知道sizeof(Foo) = 8,而x86上的寄存器位宽最大就是8,因此我们只需要读写一次就可以完成Foo Y = X这样的深拷贝了。

我们把上面的代码的汇编打印出来,可以看到下面的x86汇编:

        movl    $1, -8(%rbp)
        movw    $2, -4(%rbp)
        movb    $97, -2(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, -16(%rbp)

上面的三行代码对应的是Foo X = {1, 2, 'a'},最后两行代码就是Foo Y = X;,可以看到在汇编中第4行直接使用%rax寄存器访存,然后再向-16(%rbp)的地址处写入8字节。

如果没有内存对齐

?实际上,我们也可以要求C语言不做内存对齐的,将上面的struct Foo修改一下:

struct __attribute__((__packed__)) Foo {
  int a;
  short b;
  char c;
};

这个时候要完成一次深拷贝要稍微复杂一点,不能直接利用一个%rax寄存器,因为此时sizeof(Foo) = 7,而%rax的位宽是8,像之前的汇编代码那样做,会直接写越界。为了保证不会越界写,编译器就得一个变量一个变量地去写(对于上面的代码来说),也就是说,这里需要做三次读写。

我们再次编译上面的代码来看看:

        movl    $1, -7(%rbp)
        movw    $2, -3(%rbp)
        movb    $97, -1(%rbp)
        movl    -7(%rbp), %eax
        movl    %eax, -14(%rbp)
        movzwl  -3(%rbp), %eax
        movw    %ax, -10(%rbp)
        movzbl  -1(%rbp), %eax
        movb    %al, -8(%rbp)

头三行仍然是对应Foo X = {1, 2, 'a'},但是可以看出Foo Y = X;多了不少代码,第4,5两行实际上是Y.a = X.a,第6,7行实际上就是Y.b = X.b,紧接着第8,9两行就是Y.c = X.c

可以看出,如果没有内存对齐,struct做深拷贝的效率将会降低不少。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 20:38:18  更:2022-09-24 20:40:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:55:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码