欢迎来到代码驿站!

C代码

当前位置:首页 > 软件编程 > C代码

C++结构体字节对齐和共用体大小

时间:2022-02-23 09:41:32|栏目:C代码|点击:

1、结构体内存对齐

结构体内存对齐在笔试和面试中经常被问到,所以做个总结

通过代码验证不同结构体的内存大小:

#include <stdio.h>
struct Node1{
    char c1;
    int val1;
    char c2;
};
struct Node2{
    char c1;
    char c2;
    int val1;
};
struct Node3{
    char c1;
    char array[10];
};
struct Node4{
    char val1;
    int arrar[10];
};
int main(){
    printf("Node1 size = %d\n",sizeof(struct Node1));
    printf("Node2 size = %d\n",sizeof(struct Node2));
    printf("Node3 size = %d\n",sizeof(struct Node3));
    printf("Node4 size = %d\n",sizeof(struct Node4));

    return 0;
}

代码运行结果为:

通过上述代码运行结果可以发现Node1Node2定义了相同个数的变量,但是Node1的大小为12,Node2的大小为8,这是为什么呢?

这里首先明确两个概念:对齐数和最大对齐数,在结构体中对齐数就是每个成员类型的大小,如Node1中,对齐数为{1,4,1},在数组中,对齐数不是数组的大小,而是数组成员的大小,所以Node3的对齐数为{1,1},Node4的对齐数为{1,4}。最大对齐数是对齐数中的最大值(gcc编译器),最大对齐数可能受编译器的影响,通常编译器会有编译器对齐数,最大对齐数应该是编译器对齐数和结构体最大对齐数中较小值,如VS编译器对齐数为8,如果结构体的最大对齐数为16,那么计算结构体的最大对齐数应该为8。我的编译器为gcc,所以最大对齐数为结构体对齐数中的最大值。

知道最大对齐数后,就可以计算结构体的大小了,需要明确结构体的大小一定是最大对齐数的整数倍。那么Node1和Node2的成员类型是一样的,为什么Node1的大小为12字节,Node2的大小为8字节呢。这是因为结构体内存的连续性,在存储容量没有到最大对齐数的内存大小时,只要能够保存这个成员,结构体就会将该成员变量保存在一个最大对齐树的内存空间内。这样就避免了内存的过度浪费。

所以,上述各结构体的内存大小计算方式如下:

  • sizeof(Node1)= 1 + 3(浪费)+ 4 + 1 + 3(浪费) = 12
  • sizeof(Node2)= 1 + 1 + 2(浪费)+ 4 = 8
  • sizeof(Node3) = 1 + 1 * 10 = 11
  • sizeof(Node4) = 1 + 3(浪费)+ 4 * 10 = 44

那么结构体嵌套结构体的大小应该怎么计算呢?举以下例子:

#include <stdio.h>
struct Node1{
    char c1;
    int val1;
    char c2;
};
struct Node2{
    char c1;
    struct Node1 node;
    double val1;
};

int main(){
    printf("Node1 size = %d\n",sizeof(struct Node1));
    printf("Node2 size = %d\n",sizeof(struct Node2));
    return 0;
}

代码运行的结果为:

 可以明确,嵌套结构体的对齐数为所嵌套结构体的最大对齐数,所以Node1的对齐数为{1,4,1},Node2的对齐数为{1,4,8},最大对齐数分别为4和8,则代码里两个结构体的大小计算方式为:

  • sizeof(Node1)= 1 + 3(浪费)+ 4 + 1 + 3(浪费) = 12
  • sizeof(Node2)= 1 + 7(浪费)+ 12 + 4(浪费)+ 8 = 24

2、共用体的内存大小

对于以下共用体,读取它大小的代码如下:

#include <stdio.h>

union un1{
    int val;
    char c;
    double d;
};
union un2{
    int val;
    char array[5];
};

int main(){
    printf("un1 size = %d\n",sizeof(union un1));
    printf("un2 size = %d\n",sizeof(union un2));
    return 0;
}

代码运行结果为:

 共用体之所以叫共用体,就是因为它的成员变量共享内存,既然共享内存,那么共用体占用的内存空间一定要可以保存内存最大的成员类型,而un1的最大内存成员为double型,大小为8字节,所以un1的大小为8字节,那么un2的内存大小为什么不是5呢?这是因为要内存对齐,共用体也遵循内存对齐原则,un2的最大对齐数是4,因此un2的大小应该是4的整数倍数,所以,sizeof(un2)= 8.

3、枚举的大小

这里顺带提一下枚举的内存大小,代码验证如下:

#include <stdio.h>

enum Colour {
    RED,
    GREEN,
    BLUE
};
enum ProgramLanguage {
    python = 0xffffffffff,
    c = 8,
    java
};

int main()
{
    printf("Colour size = %d\n",sizeof(enum Colour));
    printf("ProgramLanguage size = %d\n",sizeof(enum ProgramLanguage));
    return 0;
}

代码运行结果为:

 可见枚举类型的大小是编译器根据定义的值自行给定的,实际使用中很少会超出4字节大小。

上一篇:C++实现LeetCode(倒置链表)

栏    目:C代码

下一篇:如何理解C++ 临时变量的常量性

本文标题:C++结构体字节对齐和共用体大小

本文地址:http://www.codeinn.net/misctech/194298.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有