sizeof(),C 结构中的对齐: [英] sizeof(), alignment in C structs:

查看:40
本文介绍了sizeof(),C 结构中的对齐:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前言:我对结构对齐进行了研究.看了这个问题,这个这个a> 一个 - 但仍然没有找到我的答案.

Preface: Did my research about struct alignment. Looked at this question, this one and also this one - but still did not find my answer.

我的实际问题:

这是我为了澄清我的问题而创建的代码片段:

Here is a code snippet I created in order to clarify my question:

#include "stdafx.h"
#include <stdio.h>

struct IntAndCharStruct
{
    int a;
    char b;
};

struct IntAndDoubleStruct
{
    int a;
    double d;
};

struct IntFloatAndDoubleStruct
{
    int a;
    float c;
    double d;
};

int main()
{
    printf("Int: %d\n", sizeof(int));
    printf("Float: %d\n", sizeof(float));
    printf("Char: %d\n", sizeof(char));
    printf("Double: %d\n", sizeof(double));
    printf("IntAndCharStruct: %d\n", sizeof(IntAndCharStruct));
    printf("IntAndDoubleStruct: %d\n", sizeof(IntAndDoubleStruct));
    printf("IntFloatAndDoubleStruct: %d\n", sizeof(IntFloatAndDoubleStruct));
    getchar();
}

它的输出是:

Int: 4
Float: 4
Char: 1
Double: 8
IntAndCharStruct: 8
IntAndDoubleStruct: 16
IntFloatAndDoubleStruct: 16

我在 IntAndCharStructIntAndDoubleStruct 中看到了对齐.

I get the alignment seen in the IntAndCharStruct and in the IntAndDoubleStruct.

但我就是不明白 IntFloatAndDoubleStruct 一个.

But I just don't get the IntFloatAndDoubleStruct one.

简单地说:为什么不是 sizeof(IntFloatAndDoubleStruct) = 24?

提前致谢!

ps:我使用的是 Visual-Studio 2017,标准控制台应用程序.

p.s: I'm using Visual-Studio 2017, standard console application.

根据评论,测试了 IntDoubleAndFloatStruct(元素的不同顺序)并在 sizeof() 中得到 24 - 如果答案也能注意到并解释这种情况,我会很高兴.

Per comments, tested IntDoubleAndFloatStruct (different order of elements) and got 24 in the sizeof() - And I will be happy if answers will note and explain this case too.

推荐答案

你的结构体必须是 8*N 个字节长,因为它有一个 8 个字节的成员 (double>).这意味着结构体位于内存中可被 8 整除 (A%8 == 0) 的地址 (A) 处,其结束地址将为 (A + 8N) 也可以被 8 整除.

Your struct must be 8*N bytes long, since it has a member with 8 bytes (double). That means the struct sits in the memory at an address (A) divisible by 8 (A%8 == 0), and its end address will be (A + 8N) which will also be divisible by 8.

从那里,您存储 2 个 4 字节的变量 (int + float),这意味着您现在占用了内存区域 [A,A+8).现在您存储一个 8 字节的变量 (double).由于 (A+8) % 8 == 0 [since A%8 == 0],因此不需要填充.所以,没有填充,你会得到 4+4+8 == 16.

From there, you store 2 4-bytes variables (int + float) meaning you now occupy the memory area [A,A+8). Now you store an 8-byte variable (double). There is no need for padding since (A+8) % 8 == 0 [since A%8 == 0]. So, with no padding you get the 4+4+8 == 16.

如果将顺序改为int ->双 ->float 你将占用 24 个字节,因为 double 变量原始地址不能被 8 整除,它必须填充 4 个字节才能得到一个有效的地址(而且结构也会末尾有填充).

If you change the order to int -> double -> float you'll occupy 24 bytes since the double variable original address will not be divisible by 8 and it will have to pad 4 bytes to get to a valid address (and also the struct will have padding at the end).

|--------||--------||--------||--------||--------||--------||--------||--------|
|   each ||   cell ||  here  ||represen||-ts  4  || bytes  ||        ||        |
|--------||--------||--------||--------||--------||--------||--------||--------|

A        A+4       A+8      A+12      A+16      A+20      A+24                      [addresses]
|--------||--------||--------||--------||--------||--------||--------||--------|    
|   int  ||  float || double || double ||        ||        ||        ||        |    [content - basic case]
|--------||--------||--------||--------||--------||--------||--------||--------|

first padding to ensure the double sits on address that is divisble by 8
last  padding to ensure the struct size is divisble by the largest member's size (8)
|--------||--------||--------||--------||--------||--------||--------||--------|    
|   int  || padding|| double || double || float  || padding||        ||        |    [content - change order case]
|--------||--------||--------||--------||--------||--------||--------||--------|

这篇关于sizeof(),C 结构中的对齐:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆