关于这个计算结构体变量的大小的
我印象很久之前,好像有些系统和编译器下是不对齐的,并且int是2字节,这样正好是2+21+4=27。这种就属于老题目继续拿来用,结果在现在常用的编译环境下,答案就是错的了。不用纠结这种题目,但凡负责任点的老师,就不会出到试卷上的。
这种题目,实际情况下知道怎么编程取出来占空间就行了。另外要知道怎么调整顺序能够节省占用空间。
这道题在不同系统编译器下,占用空间是不同的。
在64位系统里面,都是4字节对齐的,所以是4+24(1+20然后四字节对齐)+4=32字节,里面没有正确答案
将地址由入参传入
char* fun(char*s)
{
if (s)
strcpy(s,"abc");
return s;
}
这种方式调用都要注意给s分配的大小是足够的。
可以这样:
char* fun(char*s, int len)
{
if (s)
{
strncpy(s, "abc ", len-1);
s[len-1] = 0;
}
return s;
}
内存对齐定义: 在C语言中,为了提高程序的性能,需要对结构体变量的内存布局进行优化。其中一个内存优化手段就是内存对齐(memory alignment),也叫边界对齐。对齐的含义是指,把数据存储在地址为n的倍数的内存地址上,这样可以提高CPU访问内存的效率,加快代码运行的速度。 常见的内存对齐规则: 1. char型数据对齐值为1字节; 2. short型或unsigned short型数据对齐值为2字节; 3. int型或float型数据对齐值为4字节; 4. double型或long long型数据对齐值为8字节。 在结构体中,编译器自动进行内存对齐(注:可以使用#pragma pack(n)来指定n字节的对齐方式,但是不推荐使用)。在结构体中,对齐值是结构体中最大类型长度和平台下的对齐值中小的那个。也就是说,如果一个结构体内最长的数据类型是double型,则该结构体的对齐值是8个字节,如果平台下的对齐值是4字节,则结构体中的所有变量都按照8字节对齐。
为什么结构体变量大小是27而不是29: 假设有一个结构体如下:
struct Student{ char name[10]; int age; double score; }; 结构体变量的大小根据内存对齐规则确定。对于这个结构体,name数组的长度是10,所以按照int类型的4字节进行内存对齐,而double类型的长度为8字节,也需要按照8字节进行内存对齐。因此,这个结构体中按照8字节进行内存对齐,结构体占用的空间大小应该是24字节。但是,由于最后一个double类型变量score恰好和前面的char数组以及int类型变量age占用的空间连接到了一起,因此这个double变量会占用剩余的3个字节和int类型变量age放在一块,这样这个结构体的总大小为27字节,而不是按照预期的24字节和8字节对齐得到的32字节。这种现象称为“结构体变量的嵌套对齐”。
解决方案: 可以使用#pragma pack(1)来禁用内存对齐,这样结构体中变量的大小和排列顺序就和定义时一样,不会自动进行内存对齐。但是,这样可能会影响程序的性能,不建议使用。
可以在结构体定义时调整变量的顺序,把需要占用空间小的变量放在前面,需要占用空间大的变量放在后面,从而减少内存的浪费。比如将Student结构体重新定义如下:
struct Student{ int age; double score; char name[10]; }; 这样,结构体变量按照8字节对齐之后,占用空间大小就变成了24字节。
代码示例:
struct Student1{ char name[10]; int age; double score; };
struct Student2{ int age; double score; char name[10]; }; int main(){ printf("sizeof(Student1)=%lu\n",sizeof(struct Student1)); // 输出结果为27 printf("sizeof(Student2)=%lu\n",sizeof(struct Student2)); // 输出结果为24 return 0; }