了解C中的内存对齐约束和填充字节

时间:2015-05-26 14:51:42

标签: c struct padding sizeof

我有以下代码段。

#include<stdio.h>
int main(){
    typedef struct{
        int a;
        int b;
        int c;
        char ch1;
        int d;
    } str;
    printf("Size: %d \n",sizeof(str));
    return 0;
}

哪个输出如下

Size: 20

我知道structure的大小大于structure组件大小的总和,因为添加了填充以满足记忆对齐约束。 我想知道如何决定必须添加多少字节的填充。它取决于什么?它取决于CPU架构吗?它还取决于编译器吗?我在这里使用64位CPU和gcc编译器。如果这些参数发生变化,输出将如何变化。请有人用一些例子来解释。

我知道StackOverflow上有类似的问题,但它们没有彻底解释这种内存对齐限制。

3 个答案:

答案 0 :(得分:4)

一般取决于架构的要求。加载超过here,但可归纳如下:

  

x86或ARM处理器上的基本C数据类型的存储不会   通常从内存中的任意字节地址开始。相反,每一个   除了char之外的类型有对齐要求;字符可以从任何开始   字节地址,但2字节短路必须从偶数地址开始,4字节   整数或浮点数必须从可被4和8字节整除的地址开始   长号或双号必须从可被8整除的地址开始。签名或   无符号没有区别。

在您的情况下,可能会发生以下情况:sizeof(str) = 4 (4 bytes for int) + 4 (4 bytes for int) + 1 ( 1 byte for char) + 7 (3 bytes padding + 4 bytes for int) = 20

填充是有的,因此int的地址是4个字节的倍数。这个要求来自int长4个字节的事实(我对你正在使用的架构的假设)。但这会因建筑而异。

答案 1 :(得分:1)

  

它取决于什么?它取决于CPU架构吗?它还取决于编译器吗?

至少CPU,操作系统和编译器。

答案 2 :(得分:0)

我知道这取决于CPU架构,我认为你可以在网上找到一些有趣的文章,wikipedia在我看来并不坏。

对我来说,我使用的是64位的linux机器,而我可以说的是,每个字段都是对齐的,以便它可以在一个可被其大小整除的内存地址上(对于基本类型),例如:

div > .exam:first-of-type:before { content:attr(alt); font-style:italic; } ul { margin:0 0 1em 1em; padding:0; } li { margin-left:2em; } router.post('/login',function(req, res, next) { passport.authenticate('local', function(err, user, info) { if (err) { return next(err); } if (!user) { return res.json(null); } req.logIn(user, function(err) { if (err) { return next(err); } //return res.redirect('/'); redirect not work }); })(req, res, next); }); router.get('/check',function(req, res, next) { request.post({ url:'http://localhost/login', headers:{ 'Content-Type': 'application/x-www-form-urlencoded' }, form:{ username:'myname', password:'mypassword' }},function(err,httpRes,body){ //do here...? return res.redirect('/'); }); }); 对齐4(必须在4中整除的内存地址中)

intfloat加1(表示无填充)

charbool由8

对齐

避免填充的最佳方法是将字段从最大尺寸放到最小尺寸(当只有基本字段时)

当有合成字段时,我在这里解释起来有点困难,但我认为你可以在一篇论文中自己解决这个问题