LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1283|回复: 4

关于sizeof的问题(计算结构体的大小)

[复制链接]
发表于 2006-6-21 09:07:48 | 显示全部楼层 |阅读模式
#include <stdio.h>
struct t {
    unsigned short  c;
    int a;
};

int main(){
    printf("size = %d\n", sizeof(struct t));
};

结果是 size = 8 ???????

但是unsigned short的长度是2个字节, int的长度是4个字节, 加起来应该是6才对啊。 不清楚什么原因。

-----------------------------------------
#include <stdio.h>
struct t {
    int a;
};

int main(){
    printf("size = %d\n", sizeof(struct t));
};

结果是 size = 4.
发表于 2006-6-21 09:28:52 | 显示全部楼层
32位机器内对齐,所以是2*4byte=8;
回复 支持 反对

使用道具 举报

发表于 2006-6-24 14:14:27 | 显示全部楼层
首先我们还是定义一个结构体作为分析的对象。
        struct STRUCT {
                char    a;
                int     b;
                char    c;
        };
在C/C ++语言中,编译器给结构体分配存储空间时,是按照成员列表的顺序依次给每个成员分配存储空间。在我们所定义的STRUCT中,a和c为字符型,占用1个字节。b为整型,占用4个字节,而且它的起始存储位置必须被4整除。(注意,各变量占用字节可能在不同的机型上会有不同)。
现在我们来看一下编译器怎样在内存中实现这个结构的。
        

        =---=====---
        a           b           c

其中(=)代表占用的空间,(-)代表空余空间。

可见,当前结构STRUCT占用的空间并不是想象的1+4+1=6,而是4+4+4=12。为什么不是9呢?因为如果再次定义另一个STRUCT,而所有结构的其实存储位置必须是结构中边界要求最严格的数据类型所要求的位置。而STRUCT中要求最严的当然就是b了,上面说过,它的起始存储位置必须被4整除。所义,另一个结构的起始位置就是在第12字节了,而不是第9字节。
说到这里,我们很自然的想到了重排结构体的成员定义的顺序。较好的定义如下:
        
        struct STRUCT {
                int     b;
                char    a;
                char    c;
        };

现在,STRUCT的存储空间就是8字节了,只浪费两个字节,节约了1/3的空间。也许一般看到这并不是很有用,而且代码还不好看,凭什么先是b,后是a啊 ,但当你需要创建成千上万个这样的结构对象时,就能节省大量的存储空间,而你付出的仅仅是对代码增加一些注释而已。
回复 支持 反对

使用道具 举报

发表于 2006-6-26 06:11:19 | 显示全部楼层
Post by leeight

但是unsigned short的长度是2个字节, int的长度是4个字节, 加起来应该是6才对啊。 不清楚什么原因。


gcc -fpack-struct
回复 支持 反对

使用道具 举报

发表于 2006-6-27 15:17:39 | 显示全部楼层
Post by xphenix
较好的定义如下:
        
        struct STRUCT {
                int     b;
                char    a;
                char    c;
        };

现在,STRUCT的存储空间就是8字节了,只浪费两个字节,节约了1/3的空间。也许一般看到这并不是很有用,而且代码还不好看,凭什么先是b,后是a啊 ,但当你需要创建成千上万个这样的结构对象时,就能节省大量的存储空间,而你付出的仅仅是对代码增加一些注释而已。


为什么是8字节了,而不是4+1+1=6呢?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表