在CU的C/C++版看到一个例子:- #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长度的数组不占内存。
但是:数组长度虽然为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
在看到另一个与sizeof相关的问题:
2.某32位系统下, C++程序,请计算sizeof 的值(5分).
char str[] = “”
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[] = "";
-
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
阅读(2312) | 评论(4) | 转发(0) |