C语言为什么这个结构体变量大小是27

关于这个计算结构体变量的大小的

img


不用内存对齐吗,而且就算不用对齐,它不应该最少是29吗

我印象很久之前,好像有些系统和编译器下是不对齐的,并且int是2字节,这样正好是2+21+4=27。这种就属于老题目继续拿来用,结果在现在常用的编译环境下,答案就是错的了。不用纠结这种题目,但凡负责任点的老师,就不会出到试卷上的。
这种题目,实际情况下知道怎么编程取出来占空间就行了。另外要知道怎么调整顺序能够节省占用空间。
这道题在不同系统编译器下,占用空间是不同的。
在64位系统里面,都是4字节对齐的,所以是4+24(1+20然后四字节对齐)+4=32字节,里面没有正确答案

img

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7799876
  • 你也可以参考下这篇文章:C语言 判断一个正整数是否全由奇数数字组成或者全由偶数数字组成
  • 同时,你还可以查看手册:c语言-内存模型与数据竞争 中的内容
  • 除此之外, 这篇博客: C语言返回字符串函数的几种实现方法中的 2.函数参数传递指针,返回该指针 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 将地址由入参传入 

    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语言开发之数据结构与算法一课程中的 静态数组实现栈小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    内存对齐定义: 在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字节。

    代码示例:

    include

    pragma pack(1) // 禁用内存对齐

    struct Student1{ char name[10]; int age; double score; };

    pragma pack() // 恢复内存对齐

    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; }