如何计算结构体的大小

blpluto 2008-11-14 08:37:27
typedef struct _SizeStruct
{
int a;
union
{
long b;
short c;
};
}Sa;

Sa h[10];

这个结构体的大小怎么算呢
...全文
405 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
BenjaminLiu 2008-12-03
  • 打赏
  • 举报
回复
受教了,请问在VC6的Win32 Application Project中默认设置align pack是8啊,为什么32位的是8呢?我觉得应该是4吧.哪位高人指点一下.
blpluto 2008-11-16
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 xdkui 的回复:]
引用 23 楼 blpluto 的回复:
有点明白了,
哪double型的对齐怎么算呢

typedef struct _SizeStruct
{
char a;
int b;
double c;
}Sa;


在32bit平台, a, b, c的地址都是4字节对齐的.
见过这样的定义:
"A datum is said to be naturally aligned if its address is aligned to its size, and misaligned otherwise."
从这个定义看c实际上没有对齐, 但在32bit平台没有影响.

根据我上面说的性能考…
[/Quote]

学习了很多 非常感谢^_^
hzc191025 2008-11-15
  • 打赏
  • 举报
回复
sizeof
blpluto 2008-11-15
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 xdkui 的回复:]
假设32bit x86平台, int a占4个字节, long b占4个字节, 不需要偏移, 结构体就是8个字节.

至于
"还有#pragma pack(push,4) "
32bit平台默认就是4字节, 所以有这个原语和没有一样

你是不是想比较这两个?

C/C++ code
#pragma pack(push,4)
typedef struct _SizeStruct
{
char a;
int b;
}Sa;
#pragma pop();



C/C++ code
#pragma pack(push,1) // 1, NOT 4
typedef struct _SizeStruc…
[/Quote]

样子差不多#24
请教:我是想知道什么情况下要对齐,需要偏移量?


shuyisheng 2008-11-15
  • 打赏
  • 举报
回复
按原理说 一个结构体的大小是:sizeof(Sa)
如果说你申明的sa h[10]要占的内存空间应该是:sizeof(Sa)*10.这是实际分配值。
Rain208 2008-11-15
  • 打赏
  • 举报
回复
看编译器是否优化而言
P_ghost 2008-11-15
  • 打赏
  • 举报
回复
内置类型定义变量从大到小就可以了,呵呵
ToBeTough 2008-11-15
  • 打赏
  • 举报
回复
什么时候要内存对齐
xdkui 2008-11-15
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 blpluto 的回复:]
有点明白了,
哪double型的对齐怎么算呢

typedef struct _SizeStruct
{
char a;
int b;
double c;
}Sa;
[/Quote]

在32bit平台, a, b, c的地址都是4字节对齐的.
见过这样的定义:
"A datum is said to be naturally aligned if its address is aligned to its size, and misaligned otherwise."
从这个定义看c实际上没有对齐, 但在32bit平台没有影响.

根据我上面说的性能考虑, 我猜测c在64位平台应该是8字节对齐,不过我没有平台测试
Lnnu_lc 2008-11-15
  • 打赏
  • 举报
回复
还是考虑一下内存对齐吧,对你有好处的
blpluto 2008-11-15
  • 打赏
  • 举报
回复
有点明白了,
哪double型的对齐怎么算呢

typedef struct _SizeStruct
{
char a;
int b;
double c;
}Sa;
xdkui 2008-11-15
  • 打赏
  • 举报
回复
不好意思,最后一句说错了, 我是说对于任何int, long等4字节变量以4对齐

对于

struct
{
char a;
char b;
int c;
};

的实际内存布局是

struct
{
char a;
char b;
char padding[2];
int c;
};
xdkui 2008-11-15
  • 打赏
  • 举报
回复
可以说默认情况下, 编译器对任何变量都是4地址对齐的, 不管是单独的变量,或者是位于结构体,class里的成员
xdkui 2008-11-15
  • 打赏
  • 举报
回复
比如这个:

typedef struct _SizeStruct
{
char a;
int b;
}Sa;

32bit平台以4字节对齐,所以a的地址以4对齐, b也以4对齐, 所以a后编译器会补3字节无用数据
实际内存结构是:

typedef struct _SizeStruct
{
char a;
char padding[3];
int b
}Sa;


至于为什么要4字节对其:
1. ARM cpu只能读取4字节对其的内存地址, 如0x40000000 . 如果在ARM下直接读取0x40000001地址会有异常
但如果你制订__unaligned或者#pragma pack(push,1), 在C语言里也可以对非对齐地址访问, 但会分多步:
比如要读取以0x40000001地址开始的DWORD, 会
a. 读取0x40000000的DWORD
b. 读取0x40000004的DWORD
c. 然后编译器产生指令把这两个DWORD通过移位, 与等操作合成一个以0x40000001开始的DWORD
这里你就可以看出对不对齐地址访问的消耗相比对齐地址大了很多, 导致程序性能差

2. 有的CPU直接支持不对齐地址访问,如x86, 但会消耗更多的指令周期. 还是性能下降
xdkui 2008-11-15
  • 打赏
  • 举报
回复
假设32bit x86平台, int a占4个字节, long b占4个字节, 不需要偏移, 结构体就是8个字节.

至于
"还有#pragma pack(push,4) "
32bit平台默认就是4字节, 所以有这个原语和没有一样

你是不是想比较这两个?

#pragma pack(push,4)
typedef struct _SizeStruct
{
char a;
int b;
}Sa;
#pragma pop();



#pragma pack(push,1) // 1, NOT 4
typedef struct _SizeStruct
{
char a;
int b;
}Sa;
#pragma pop();
johnelf 2008-11-14
  • 打赏
  • 举报
回复
sizeof(Sa)
toadzw 2008-11-14
  • 打赏
  • 举报
回复
只要考虑union中的最大的要分配多少内存就可以了;有些情况下要考虑内存对齐
bill830711 2008-11-14
  • 打赏
  • 举报
回复
1:简单的 先不考路边界对其
则union去最大字段
结构体的大小为 long+int -》 4+4 = 8

2:在考虑边界对齐,对齐的条件如7楼所说
那么该结构体 int 和long 都是对齐的

但如果蒋union中的long 改为long long(8字节处对齐)
则不考虑边界对齐 为 int+long long -》 4+ 8=12
考虑边界对齐,则longlong 必须在8字节处,而int后面的起始处在4字节对齐处,所以必须空处4个字节,然后才是long long的位置
Non_Recursive 2008-11-14
  • 打赏
  • 举报
回复
sizeof(sa)
blpluto 2008-11-14
  • 打赏
  • 举报
回复
我知道sizeof 我现在是想知道sizeof是怎么算的
还有#pragma pack(push,4)
typedef struct _SizeStruct
{
int a;
union
{
long b;
short c;
};
}Sa;

Sa h[10];
#pragma pop();
又是怎么算的呢
加载更多回复(8)

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧