在CU的C/C++版看到一个例子:http://bbs.chinaunix.net/thread-3621056-1-1.html
比较三者,按照三者中最小的来对齐。
- #include <stdio.h>
-
- struct A{
- char a;
- char b;
- int c[0];
- };
-
- struct B{
- char a;
- char b;
- int c;
- };
-
- int main()
- {
- printf("sizeof(struct A): %d\n", sizeof(struct A));
- printf("sizeof(struct B): %d\n", sizeof(struct B));
-
- return 0;
- }
结果:
- digdeep@ubuntu:~/uulp$ gcc -Wall -o sizeof sizeof.c
- digdeep@ubuntu:~/uulp$ ./sizeof
- sizeof(struct A): 4
- sizeof(struct B): 8
- digdeep@ubuntu:~/uulp$
C语言在编译时的对齐规则:
1)找出struct 结果体中占用内存最大的类型(__alignof__(type)最大的类型),在struct A,struct B中都是int。
2)知道常识:编译指标器(#pragma pack(X),x86机器上默认X一般是4。
3)机器字长 (32位/64位)
注:有个容易误解的地方,占用内存最大的类型,不是指sizeof最大的那个,而是指__alignof__(type)最大的那个,double在32位上,可以为4和8,默认为4,可由编译参数控制,如果编译时加上-malign-double,__aignof__(double)值由4变成了8。(一般除了double之外,其它的类型sizeof(type) == __alignof__(type) )
比较三者,按照三者中最小的来对齐。
因为
__alignof__(int) ==
sizeof(int) == 4,所以struct A和struct B都是按照4字节对齐。
所以:sizeof(struct A) == 4, sizeof(struct B) == 8
在struct A中应该说int c[0]并不占用内存。也就是0长度的数组不占内存。
在struct A中应该说int c[0]并不占用内存。也就是0长度的数组不占内存。
但是:数组长度虽然为0,但是却影响了结构体整体的对齐
一个类型的对齐值,可通过操作符__alignof__(type)得到:
struct A{
char a;
char b;
int a[0];
};
在编译器默认对齐方式的情况下,结构体内成员所在位置必须为其自身类型的整数倍,即short型必须在__aignof__(short) * n == 2n 的位置上开始存储。int 型必须在__aignof__(int)*n == 4n,double型必须在__aignof__(double)*n ==4n != 8n的位置上开始存储。而对于0长数组的情况,这个数组只是看上去在结构体里面,实际上并不能算是结构体的正式成员。
但是我们使用他的时候需要把他当做结构体的成员使用。
结构体 struct A 当中,
由于最后一个成员是int c[0], 在为结构体分配空间时,按照int 类型对齐。
假设 A.a地址为0xbfd1c, 则A.b地址为0xbfd1d, 则数组c的起始地址为0xbfd1d往后2位(按照int类型对齐),即为0xbfd20,
但是c[0]不分配空间不占空间所以sizeof(A)=4
示例:
- #include <stdio.h>
-
- struct A{
- char a;
- char b;
- double d;
- };
-
- int main()
- {
- printf("sizeof(struct A): %d\n", sizeof(struct A));
- return 0;
- }
编译运行结果:
- digdeep@ubuntu:~/uulp$ gcc -Wall -o sizeof sizeof.c
- digdeep@ubuntu:~/uulp$ ./sizeof
- sizeof(struct A): 12
- digdeep@ubuntu:~/uulp$ gcc -Wall -malign-double -o sizeof sizeof.c
- digdeep@ubuntu:~/uulp$ ./sizeof
- sizeof(struct A): 16
- digdeep@ubuntu:~/uulp$
可以看出,加了 -malign-double 选项时,结果为16,没有加 -malign-double 选项时,结果为12.
加了 -malign-double 选项时,强调按照double的sizeof(double)的大小来对齐。
在看一看几个例子:
- #include <stdio.h>
-
- struct A{
- char a;
- char b;
- };
-
- struct B{
- char a;
- char b;
- double c;
- };
-
- struct C{
- char a;
- };
-
- struct D{
- char a;
- short c[0];
- };
-
- struct E{
- char a;
- int c[0];
- };
-
- int main()
- {
- printf("sizeof(struct A): %d\n", sizeof(struct A));
- printf("sizeof(struct B): %d\n", sizeof(struct B));
- printf("sizeof(struct C): %d\n", sizeof(struct C));
- printf("sizeof(struct D): %d\n", sizeof(struct D));
- printf("sizeof(struct E): %d\n", sizeof(struct E));
-
- return 0;
- }
结果:
- digdeep@ubuntu:~/uulp$ gcc -Wall -o sizeof2 sizeof2.c
- digdeep@ubuntu:~/uulp$ ./sizeof2
- sizeof(struct A): 2
- sizeof(struct B): 12
- sizeof(struct C): 1
- sizeof(struct D): 2
- sizeof(struct E): 4
在http://bbs.chinaunix.net/thread-3636905-1-3.html看到另一个与sizeof相关的问题:
2.某32位系统下, C++程序,请计算sizeof 的值(5分).
char str[] = “ http://www.ibegroup.com/ ”
char *p = str ;
int n = 10;
请计算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
请计算
sizeof( str ) = ?(4)
}
void *p = malloc( 100 );
请计算
sizeof ( p ) = ?(5)
char str[] = “ http://www.ibegroup.com/ ”
char *p = str ;
int n = 10;
请计算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
请计算
sizeof( str ) = ?(4)
}
void *p = malloc( 100 );
请计算
sizeof ( p ) = ?(5)
答:(1)25 (2)4 (3) 4 (4)4 (5)4
此题的关键是看:sizeof() 计算的到底是什么类型的变量的大小!!!
第一个sizeof(str),很明显str是将一个字符串赋值给一个字符数组,所以答案应该是数组的大小。是25而不是24,因为最后还有结尾符:‘/0‘
第二个sizeof(p),很明显p是一个指针,所以在32为机器上大小为4字节
第三个sizeof(n),很简单,32为机器上int为4字节
第四个sizeof(str),应该注意该"str"是一个参数,我们知道C中数组作为参数,实际上传递的是数组的第一个元素的地址,所以"str"是一个指针,所以sizeof(str)等于4
第五个sizeof(p),p也是指针,所以大小为4.
这里特别要注意的是第一个和第四个!
第一个等于25而不是24要特别注意,因为是将一个字符串赋值给字符数组,而字符串是有结尾符的!!!
看下面代码的运行结果:
- #include <stdio.h>
- #include <stdlib.h>
-
- void foo(char str[100])
- {
- printf("sizeof(str3): %d\n", sizeof(str));
- }
-
- int main()
- {
- char str[] = "http://www.ibegroup.com/";
- char str2[] = {'h', 't', 't','p',':','/','/',
- 'w','w','w','.','i','b','e','g','r','o','u','p',
- '.','c','o','m','/'};
- char *p = str ;
- int n = 10;
- void *p1 = malloc(100);
-
- printf("sizeof(str): %d\n", sizeof(str));
- printf("sizeof(str2): %d\n", sizeof(str2));
- printf("sizeof(p): %d\n", sizeof(p));
- printf("sizeof(n): %d\n", sizeof(n));
- printf("sizeof(p1): %d\n", sizeof(p1));
- foo(str);
-
- return 0;
- }
运行结果:
- digdeep@ubuntu:~/uulp$ ./sizeof
- sizeof(str): 25
- sizeof(str2): 24
- sizeof(p): 4
- sizeof(n): 4
- sizeof(p1): 4
- sizeof(str3): 4