0
点赞
收藏
分享

微信扫一扫

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。

🚩write in front🚩   

🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎

🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星TOP100~2022博客之星TOP63~作者周榜84﹣作者总榜704~阿里云专家博主 & 阿里云星级博主~掘金优秀创作者⇿InfoQ创作者⇿51CTO红人⇿全网访问量50w+🏅

🆔本文由 謓泽 原创 如需转载还请通知⚠

📝个人主页-​​謓泽51Ctop的博客​​📃

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝

📣系列专栏-​​謓泽51Ctop的博客_【C语言】从0~1_51CTO博客​​🎓
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_偏移量

为什么存在内存对齐 

平台原因→移植原因:不是所有的硬件平台上都能访问任意地址上的任意数据的,某些硬件平台上只能在某些地址处某些特定的数据,不然会抛出硬件异常。

性能原因:数据结构尤其是栈,应该尽可能地在自然边界对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问。

总的来说→结构体的内存对齐是拿空间来换取时间的做法。

当然在设置结构体的时候我用成员较小的话存放在一起这样是可以节省内存空间的。

如下代码所示 ↓ 

#include<stdio.h>
struct B1
{
int name;
char c;
char c1;
};
int main(void)
{
struct B1 s1 = { 0 };
printf("s1:%d\n", sizeof(s1));

return 0;
}

如何修改默认对齐数 

在上面当中提到过vs的默认对其数是⑧,那么我们是否或者怎么样才能够修改这个默认对其数。如下代码所示 ↓ 

#include<stdio.h>
struct S8
{
char c;//0
//浪费1~3
int name;//4~7
char c1;//8
//浪费9~11
//总共字节大小为12
};
int main(void)
{
printf("S8:%d\n", sizeof(struct S8));
return 0;
}

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_#include_02

运行结果↓

S8:12 

那么上述代码当中的默认对齐数是8,注-vs默认对齐数都是8。那么我们如何把默认对齐数修改成大小为2❓那么如下所示↓

#pragma pack (2)

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_#pragma_03

在这里我们加上这句代码的话就可以把我们默认对齐数从⑧修改成②了

如下代码所示↓

#include<stdio.h>
#pragma pack (2)
struct S8
{
char c;
int name;
char c1;

};
#pragma pack ()//把修改的给取消掉
int main(void)
{
printf("S8:%d\n", sizeof(struct S8));
return 0;
}

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_#include_04

运行结果↓

S8:8

那么在这里我们的程序运行结果就是为8了,那么这是为什么。如下图列表所示↓

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_偏移量_05

那么当我们上面改成默认对齐数是1的话,那所有的都会是1的倍数了。 大小就不存在什么浪费不浪费了。 

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_#include_06

offsetof() - 查询偏移量

该函数的同文件是→#include<stddef.h>

offsetof()函数声明如下 ↓

offsetof (type,member)

【C语言】为什么存在内存对齐、如何修改默认对齐数、offsetof() - 查询偏移量。_#pragma_07

  • 该宏以函数形式返回成员成员在数据结构或联合类型中的字节偏移值。
  • 返回的值是size_t类型的无符号整型值,包含指定成员与其结构体开头之间的字节数。 

如下代码所示 ↓ 

#include<stdio.h>
#include<stddef.h>
struct S8
{
char c;//0
//浪费1~3
int name;//4~7
char c1;//8
//浪费9~11

};
int main(void)
{
printf("偏移量→%d\n", offsetof(struct S8,c));
printf("偏移量→%d\n", offsetof(struct S8, name));
printf("偏移量→%d\n", offsetof(struct S8, c1));
return 0;
}

运行结果如下 ↓

偏移量→0

偏移量→4

偏移量→8

由于结构体的传参部分在上一篇结构体当中说过,这里就不再过多追述。

举报

相关推荐

0 条评论