请教linux下gcc下内存对齐的原则

feiyu_lili 2008-09-04 10:46:41
我有以下代码

#include <stdio.h>
//#pragma pack(4)

typedef struct Test_Struct
{
 double d_var;
 char c_var1;
 short s_var;
 char c_var2;
} Test_Struct;

int main()
{
 Test_Struct test_struct;

 double *p_d = &test_struct.d_var;
    char *p_c1 = &test_struct.c_var1;
    short *p_s = &test_struct.s_var;
    char *p_c2 = &test_struct.c_var2;
   
    printf("test_structのサイズは:%d\n",sizeof(test_struct)); 
    printf("d_varの位置:%d\n",p_d);
    printf("c_var1の位置:%d\n",p_c1);
    printf("s_varの位置:%d\n",p_s);
    printf("c_var2の位置:%d\n",p_c2);
   
    system("pause");
    return 0;
}
运行结果是
test_structのサイズは:16
d_varの位置:2293600
c_var1の位置:2293608
s_varの位置:2293610
c_var2の位置:2293612

我知道在linux的gcc下默认的是四字节的。
也能看出他现在的分配是
8+2+2+4
且我查到有1.默认为4字节的对齐方式,所以小于4字节的类型都占4字节.这种说法
那1这种说法不是应该分配为8+4+4+4啊。为什么是8+2+2+4
还有不是8+1+2+1更合理吗。
这和他默认的4字节有什么关系
...全文
1889 69 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
69 条回复
切换为时间正序
请发表友善的回复…
发表回复
quanhao8 2010-08-11
  • 打赏
  • 举报
回复
内存对齐 大家都对它这么了解啊
myeclipse0123 2010-08-09
  • 打赏
  • 举报
回复
我认为64楼说的比较靠谱。。
shouwangzhe1981 2009-03-15
  • 打赏
  • 举报
回复
内存对齐大家还是很关心的。
xiabeizi 2009-03-06
  • 打赏
  • 举报
回复
好老的一个贴子,呵,不过学习了!!!!!

这么热闹,LZ怎么没结帐呢?不会自己学了东西偷着乐去了吧,呵
zhentoubaobao 2008-09-17
  • 打赏
  • 举报
回复
linux群8709932 欢迎大家加入
hao117 2008-09-17
  • 打赏
  • 举报
回复
当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小不产生任何效果。

结构体所占字节数应该是Min[编译器最大对齐数, 数据类型最大对齐数]的整数倍
theey 2008-09-10
  • 打赏
  • 举报
回复
汗。。。没仔细看前面的,献丑了
快乐田伯光 2008-09-10
  • 打赏
  • 举报
回复
跟7楼一个意思啊
[Quote=引用 61 楼 theey 的回复:]
经过我的初步研究是这样的,有表述不当,请谅解:
单字节类型的地址可任意分配,双字节的要从2的整数倍开始,4字节的从4的整数倍开始,8字节的从4的整数倍开始。在这个基础上,默认情况下,gcc在32位cpu环境下对于结构体是按4字节对齐的,也就是结果是4的整数倍,对于上述情况的结果,不够补齐。如果结构这样定义(为方便其它省略了啊):(排名分先后)
char a; char b; double c; char d; short e; 一共是是16. 开始算:两个…
[/Quote]
theey 2008-09-10
  • 打赏
  • 举报
回复
经过我的初步研究是这样的,有表述不当,请谅解:
单字节类型的地址可任意分配,双字节的要从2的整数倍开始,4字节的从4的整数倍开始,8字节的从4的整数倍开始。在这个基础上,默认情况下,gcc在32位cpu环境下对于结构体是按4字节对齐的,也就是结果是4的整数倍,对于上述情况的结果,不够补齐。如果结构这样定义(为方便其它省略了啊):(排名分先后)
char a; char b; double c; char d; short e; 一共是是16. 开始算:两个char,2字节,double要从4倍开始,补齐两个,加上double的8个字节,现在是12个字节,又一个char,13个字节,short只需从2倍开始,补一个就够了,14个字节,再加上short的2个字节,一共16字节。又是4的整数倍,这就是了。
如果换下把倒数第二个char拿掉,一共还是16个字节。因为这样算出来14个字节不是4的倍数,要加上2字节,是16字节了。
。。。问下,为啥不让贴图片啊?
lurenfu 2008-09-05
  • 打赏
  • 举报
回复
测试如下:

#include <stdio.h>

struct a {
double a;
char b;
};

int main()
{
printf( "%d\n", sizeof(struct a) );
return 0;
}


机器是32位的x86,P4的CPU,没用任何编译选项,直接gcc -o aaa aaa.c,输入结果是12,而不是16。
realdragon2 2008-09-04
  • 打赏
  • 举报
回复
确实有一点错了,改正:)

结构体所占字节数应该是编译器最大对齐模数的整数倍.

[Quote=引用 2 楼 realdragon2 的回复:]
从地址描述来看, 后面三个变量所分配的内存都是2个字节,也就是8+2+2+2=14,但是结构体对齐有一个原则: 结构体所占字节总数是其最大类型字节数(这里是8)的整数倍, 所以在最后一个变量的后面又分配了2个字节给这个结构体让它满足这个原则.
[/Quote]
realdragon2 2008-09-04
  • 打赏
  • 举报
回复
嗯?

GCC编译器的对齐模数最大是4啊,所以,你这个结构体大小是: 4+(4+4)=12,两个4分配被double类型的b变量.


原楼主输出的地址中,可以看出第2个和第3个变量所占的是2两个字节,最后一个变量只输出了一个地址. 你可以在原先结构体的后面再加一个变量,然后看看最后一个变量占了几个字节.

[Quote=引用 3 楼 guosha 的回复:]
肯定不是这样,你可以看看这个结构的大小


C/C++ code
struct
{
char a;
double b;
};




照你的理论该是8 + 8 = 16了, 事实我觉得应该是 4 + 8 = 12
引用 2 楼 realdragon2 的回复:
从地址描述来看, 后面三个变量所分配的内存都是2个字节,也就是8+2+2+2=14,但是结构体对齐有一个原则: 结构体所占字节总数是其最大类型字节数(这里是8)的整数倍, 所以在最后一个变量的后面又分配了2个字节给这个结构体…
[/Quote]
快乐田伯光 2008-09-04
  • 打赏
  • 举报
回复
肯定不是这样,你可以看看这个结构的大小


struct
{
char a;
double b;
};


照你的理论该是8 + 8 = 16了, 事实我觉得应该是 4 + 8 = 12
[Quote=引用 2 楼 realdragon2 的回复:]
从地址描述来看, 后面三个变量所分配的内存都是2个字节,也就是8+2+2+2=14,但是结构体对齐有一个原则: 结构体所占字节总数是其最大类型字节数(这里是8)的整数倍, 所以在最后一个变量的后面又分配了2个字节给这个结构体让它满足这个原则.
[/Quote]
realdragon2 2008-09-04
  • 打赏
  • 举报
回复
从地址描述来看, 后面三个变量所分配的内存都是2个字节,也就是8+2+2+2=14,但是结构体对齐有一个原则: 结构体所占字节总数是其最大类型字节数(这里是8)的整数倍, 所以在最后一个变量的后面又分配了2个字节给这个结构体让它满足这个原则.
快乐田伯光 2008-09-04
  • 打赏
  • 举报
回复
就应该是8+ 2 + 2 + 4,

总指导原则是4字他对齐,然后是四字节内部,以紧随其后的成员size对齐,如short, char, short,为2 + 2 + 4,而short , char ,char为2+1+1, 而char + int为4 + 4
Locom 2008-09-04
  • 打赏
  • 举报
回复
不好意思,看理解了。
Locom 2008-09-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 king820802 的回复:]
8+1+1+2+1+3=16
[/Quote]

那这样不是和楼主程序的结果有存在不同。
test_structのサイズは:16
d_varの位置:2293600
c_var1の位置:2293608
s_varの位置:2293610
c_var2の位置:2293612


新手,请指教!
快乐田伯光 2008-09-04
  • 打赏
  • 举报
回复
fierygnu, 帮我看看这个帖

http://topic.csdn.net/u/20080904/15/bf8cdb20-65a9-49ec-9ef1-d1fa148839f7.html
fierygnu 2008-09-04
  • 打赏
  • 举报
回复
哦,程序员指定pack方式是另一回事。
快乐田伯光 2008-09-04
  • 打赏
  • 举报
回复
哪里的文献?

他们上面用的是gcc编译器哦,linux下的结果

[Quote=引用 52 楼 fierygnu 的回复:]
很热闹:)

是这样的:在x86上
* A char (one byte) will be 1-byte aligned.
* A short (two bytes) will be 2-byte aligned.
* An int (four bytes) will be 4-byte aligned.
* A float (four bytes) will be 4-byte aligned.
* A double (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux.

现在可以解释了吧?
[/Quote]
加载更多回复(49)

23,217

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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