C语⾔sizeof求结构体⼤⼩问题汇总
可以说⼀直被各类结构体⼤⼩问题所困扰,花了⼤半天时间查了⼀下资料,现在整理汇总如下。
sizeof:C语⾔中判断数据类型或者表达式长度符;不是⼀个函数,字节数的计算在程序编译时进⾏,⽽不是在程序执⾏的过程中才计算出来。
基本数据类型的⼤⼩很好计算,我们主要看⼀下构造数据类型的⼤⼩,包括数组,结构体和共⽤体。
1、数组类型,计算单个元素的⼤⼩,整个数组⼤⼩就是单个元素⼤⼩乘以元素个数。
char a[] = "abc";
char b[100] = "abc";
......
sizeof(a); // =4 , 字符数组末尾⾃动添加 '\0'
sizeof(b); // =100,内存中预分配的⼤⼩为100 ×1
2、结构体类型,⼤⼩不是每个结构体成员的简单相加,需要考虑到系统存储时结构体变量地址对齐的⼀系列问题。
sizeof 指针1)结构体的⼤⼩等于结构体内最⼤成员⼤⼩的整数倍
2)结构体内的成员的⾸地址相对于结构体⾸地址的偏移量是其类型⼤⼩的整数倍,⽐如说double型成员相对于结构体的⾸地址的地址偏移量应该是8的倍数。
3)为了满⾜规则1和2编译器会在结构体成员之后进⾏字节填充!
struct{
int a;
static int b;
}Q;
sizeof(Q); // Q=4, 静态变量是存放在全局数据区的,⽽sizeof计算栈中分配的⼤⼩,是不会计算在内的。
tips: 32位系统,int ⼤⼩为4,char⼤⼩为1,float⼤⼩为4,double⼤⼩为8。
3、结构体中包含结构体的情况
⼀个完整的测试程序如下:
struct test_st1{
char a;
long b;
};
struct test_st2{
char c;
struct test_st1 st1;
long long d;
};
int main() {
struct test_st2 t;
int x1 = (unsigned int)(void*)&t.c - (unsigned int)(void*)&t;
int x2 = (unsigned int)(void*)&t.st1.a - (unsigned int)(void*)&t;
int x3 = (unsigned int)(void*)&t.st1.b - (unsigned int)(void*)&t;
int x4 = (unsigned int)(void*)&t.d - (unsigned int)(void*)&t;
printf("a=0x%p,b=0x%p,c=0x%p,d=0x%p", x1, x2, x3, x4);
system("pause");
}
主要来看⼀下结构体test_st2这个结构体,c是本⾝是⼀个字节,所以对齐⽅式是1,⽽st1是⼀个结构,
那么这个结构本⾝在其他结构体中,对齐的⽅式是什么呢,是以结构体的⼤⼩和给定的对齐⽅式做⽐较吗?不对,它的对齐⽅式是它成员变量中最⼤的那个成员变量所占的内存空间和给定的值进⾏⽐较,继⽽,st1的对齐⽅式是4,它的起始地址是可以整除4的地⽅开始。 对于d,因为它占⽤8个字节的内存,所以它的对齐⽅式是8,c和st1⽤去了12个字节,所以d从内存地址可以整除8的地⽅开始存放,所以这个test_st2结构体的⼤⼩是24。测试结果如图:
4、⼏个常见⾯试题
a). sizeof在计算变量所占空间⼤⼩时采取的机制;
结构体的⼤⼩等于结构体内最⼤成员⼤⼩的整数倍;结构体内的成员的⾸地址相对于结构体⾸地址的偏移量是其类型⼤⼩的整数倍,⽐如说double型成员相对于结构体的⾸地址的地址偏移量应该是8的倍数。
b).如果是⾃⼰为⼀个类写⼀个sizeof函数,应该考虑哪些问题
⽅式⼀:
#define SIZEOF(X) (int)((X)+1) - (int)(X)
char a[2]; //定义⼀个同类型的数组,两个元素的地址差就是该类型数据所占字节数
printf("%d", SIZEOF(a));  //这⾥的可以求任意数据类型的所占的字节数。
⽅式⼆:
#define my_sizeof(L_Value)  (char* )(&L_Value + 1) - (char* ) (&L_Value)
int main(void)
{
char a;
printf("%d", my_sizeof(a));
system("pause");
}
c).虚函数和虚继承对于⼀个类求sizeof的影响有什么差别
class A {
public:
virtual void funa();
virtual void funb();
void func();
static void fund();
static int si;
private:
int i;
char c;
};
问:sizeof(A) = ?
解答:
关于类占⽤的内存空间,有以下⼏点需要注意:
(1)如果类中含有虚函数,则编译器需要为类构建虚函数表,类中需要存储⼀个指针指向这个虚函数表的⾸地址,注意不管有⼏个虚函
数,都只建⽴⼀张表,所有的虚函数地址都存在这张表⾥,类中只需要⼀个指针指向虚函数表⾸地址即可。 (2)类中的静态成员是被类所有实例所共享的,它不计⼊sizeof计算的空间
(3)类中的普通函数或静态普通函数都存储在栈中,不计⼊sizeof计算的空间
(4)类成员采⽤字节对齐的⽅式分配空间
答案:12(32位系统)或16(64位系统)
可参考右边:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。