精华内容
下载资源
问答
  • C语言结构体对齐规则与0字节数组@[TOC](C语言结构体对齐规则与0字节数组)C语言结构体对齐规则对齐规则说明 C语言结构体对齐规则 不同的编译器和系统默认的对齐规则会有差异,这里我使用的32bit的MinGW。 对齐规则...

    C语言结构体对齐规则

    不同的编译器和系统默认的对齐规则会有差异,这里我使用的32bit的MinGW。

    1、结构对齐

    对齐规则说明:

    • 规则一:struct内的第一个成员在偏移地址0处,随后成员的偏移地址在其本身字节大小整数倍处。
    • 规则二:struct的总大小为内部最大成员的整数倍
    • 规则三:当A结构内含有结构B时,B在A中的偏移地址为B结构成员内最大元素的整数倍

    示例1:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    #define debug_printf(value) printf(#value " ---==> %d\n", value)
    
    #define struct_member_offset(struct, member) (((char *)(&(((struct *)0)->member))) - ((char *)0))
    
    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t  c;
    	uint8_t  d;
    }test_t;
    
    int main()
    {
    	int a = struct_member_offset(test_t, a);
    	int b = struct_member_offset(test_t, b);
    	int c = struct_member_offset(test_t, c);
    	int d = struct_member_offset(test_t, d);
    	debug_printf(sizeof(test_t));
    	debug_printf(a);
    	debug_printf(b);
    	debug_printf(c);
    	debug_printf(d);
    	return 0;
    }
    
    

    输出结果:
    在这里插入图片描述
    解析:

    • a为第一个成员在偏移地址0处
    • b成员类型为无符号整形占用四字节,根据规则一b要对齐到4字节地址处,所以偏移地址为4,相当于在a成员后面补齐了3字节
    • c和d成员大小都为1字节,根据规则一要对齐到1字节,所以c偏移为9,d偏移为10
    • 四个成员目前所占用的空间加起来是10字节,但是!此时还没完!根据规则二结构体的总大小为结构内最大成员的整数倍,test_t这个结构内最大成员是b占用4字节,所以10字节还要补齐2字节去对齐4字节,所以sizeof(test_t)=12。

    示例二:

    现在将d成员改为uint64类型:

    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t  c;
    	uint64_t  d;
    }test_t;
    

    输出结果:

    还是根据规则解析:

    • a在偏移地址0处
    • b在4处
    • c在8处
    • abc所占用的空间为9个字节,d为uint64类型占8个字节,所以要对齐到8字节处,也就是偏移地址16处,相当于c成员后补齐了7字节。
    • 目前四个成员所占用的空间为24字节,24是d类型的倍数大小,所以sizeof(test_t)=24

    示例三:
    现在将结构改为如下,多了一个数据

    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t c[3];
    	uint8_t  d;
    	uint64_t  e;
    }test_t;
    
    

    输出结果:
    在这里插入图片描述
    c成员为3字节,占用偏移地址8,9,10三个空间,所以总大小还是24。


    示例四:
    将结构改为如下,现在test_t结构内包含结构sub_t。

    typedef struct
    {
    	uint8_t sub_a;
    	uint32_t sub_b;
    }sub_t;
    
    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	sub_t c;
    	uint8_t  d;
    	uint64_t  e;
    }test_t;
    

    输出结果:
    在这里插入图片描述

    解析:

    • 根据规则一和二解析sizeof(sub_t)=8字节
    • 根据规则三确定sub_t在test_t中的偏移地址肯定是4的整数倍处,所以c这个结构成员偏移地址为8
    • d偏移地址为17
    • e偏移地址为24
    • sizeof(test_t)=32

    2、字节为0的数组与结构体

    先看一下0字节数组的大小:

    int main()
    {
    	int array[0];
    	debug_printf(sizeof(array));
    	return 0;
    }
    

    输出结果:

    sizeof(array) ---==> 0
    

    说明0字节数据占用空间为0,那么看下面这个例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    #define debug_printf(value) printf(#value " ---==> %d\n", value)
    
    #define struct_member_offset(struct, member) (((char *)(&(((struct *)0)->member))) - ((char *)0))
    
    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t  c;
    	uint64_t  d[0];
    }test_t;
    
    int main()
    {
    	int a = struct_member_offset(test_t, a);
    	int b = struct_member_offset(test_t, b);
    	int c = struct_member_offset(test_t, c);
    	int d = struct_member_offset(test_t, d);
    	debug_printf(sizeof(test_t));
    	debug_printf(a);
    	debug_printf(b);
    	debug_printf(c);
    	debug_printf(d);
    	return 0;
    }
    

    输出结果:
    在这里插入图片描述
    !!奇怪的问题出现了!!

    但道理说d成员占用空间为0,sizeof(test_t)应该是12才对,但是sizeof(test_t)却是16!!

    原因:d成员虽然占用空间为0,但是他是uint64类型的,结构体的总大小是按照内部最大成员进行对齐的!test_t对齐到了8字节,所以sizeof(test_t)的大小为16字节!


    ends…

    展开全文
  • c语言结构体对齐规则

    2017-09-07 09:11:44
    1.第一个成员在与结构体变量偏移量为0的地址处。 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 //对齐数 = 编译器默认的一个对齐数 与...4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的对齐数

    1.第一个成员在与结构体变量偏移量为0的地址处。
    2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    //对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的值为8
    linux中的默认值为4
    3.结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。
    4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的对齐数的整数倍处(结构体的对齐数为其成员中的最大对齐数),结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

    展开全文
  • C语言结构体对齐规则

    2019-03-12 10:55:59
    最近在看操作系统,下面这篇文章对内存对齐讲解的非常通俗易懂,推荐一下: https://www.cnblogs.com/tsw123/p/5837273.html

    最近在看操作系统,下面这篇文章对内存对齐讲解的非常通俗易懂,推荐一下:

    https://www.cnblogs.com/tsw123/p/5837273.html

    展开全文
  • C语言结构体对齐、枚举、宏、联合体结构体对齐问题枚举常量与宏的区别联合体和结构体区别C和C++结构体区别 结构体对齐问题 关于结构体对齐问题请阅读:结构体对齐规则及举例 系统指定类型的大小与系统有关,这里取 ...

    结构体对齐问题

    关于结构体对齐问题请阅读:结构体对齐规则及举例

    系统指定类型的大小与系统有关,这里取

    数据类型 字节
    char 1
    float 4
    double 8
    long double 16
    short int 2
    int 4
    long int 8
    long long int 8

    (1)按结构体最大成员对齐(32位机下double、long long按照4字节对齐)
    案例一:

    struct A{
    	char a;
    	short b;
    	int a;	
    };
    

    结果是8

    案例二:

    struct A{
    	int a;
    	double b;
    };
    

    结果是12并非16

    (2)结构体嵌套
    嵌套的结构体会在先内部完成对齐。
    案例一:

    struct A{
    	short a;
    	char b;
    };
    struct B{
    	struct A b;
    	char c;
    	int d;
    };
    

    结果是12,而非8
    如果是:
    案例二:

    struct A{
    	short a;
    	char b;
    	char c;
    	int d;
    };
    

    则是8

    (3)每个成员的起始位置必须是当前成员大小的整数倍
    例如:

    • short的起始位置必须是2的倍数。
    • int、long long、double的起始位置必须是4的倍数。
    • char则随便放,因为是1。
    struct A{	
    	char a;
    	short b;
    	int c;
    };
    

    b的偏移是2而非1

    (4)在使用预编译指令指定对齐方式之后,一切听预编译指令
    #pragma pack(nbytes)可以指定按nbytes字节对齐。

    枚举常量与宏的区别

    • 枚举常量属于常量,但宏不是常量;
    • 枚举常量具有类型,但宏没有类型,枚举变量具有与普通变量相同的诸如作用域、值等性质,但宏没有,宏不是语言的一部分,它是一种预处理替换符。枚举类型主要用于限制性输入,例如,某个函数的某参数只接受某种类型中的有限个数值,除此之外的其它数值都不接受,这时候枚举能很好地解决这个问题。能用枚举尽量用枚举,否则在调试的时候你是看不到当时的值的。
    • 枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。

    联合体和结构体区别

    两者都可以有多个成员,结构体是多个不同类型变量的组合,其占用的内存大小是所有变量大小的总和; 联合体多个不同类型的变量占用一份存储空间,其占用内存的大小是联合体中最大的那个变量的大小。

    由于共用一份存储空间,所以对联合体的成员进行修改会顺带改变其他成员,结构体则不会。

    C和C++结构体区别

    • C的结构体内不允许有函数成员存在,C++允许有内部成员函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
    • C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
    • C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
    • 创建结构体对象的书写不同,C++直接用结构体名 变量名;而C要struct 结构体名 变量名;
    • C结构体不可以有static成员。
    展开全文
  • C语言结构体对齐

    2019-06-24 23:43:01
    1、字节对齐概念 现代计算机中,内存空间按照字节划分,...2、结构体对齐C语言中,结构体是种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组...
  • C语言结构体对齐问题详解 测试环境32位机 WinXP: 编译器VC6(MS cl.exe ) 和 mingw32-gcc-4.5.2   1 结构体数据对齐(没有#pragma pack()宏定义) 结构体对齐可以总结为三个基本原则 ①数据成员...
  • c语言结构体对齐

    2010-11-03 14:02:00
    <br />C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。结构体到底怎样对齐?下面总结了对齐原则,在没有#pragma pack宏的情况下: 原则1、普通数据成员对齐规则:第一个数据成员放在...
  • c语言结构体对齐

    千次阅读 2010-10-10 15:09:00
    C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这...
  • 30.C语言结构体对齐访问

    千次阅读 2016-04-04 13:05:05
    30.1.C语言之结构体概述 30.2.从数组到结构体的进化 30.3.访问结构体和数组中的元素 30.4.结构体对齐访问的...结构体对齐规则和运算 30.6.gcc支持但不推荐的对齐指令 30.7.gcc推荐的对齐指令 30.8.参考阅读博客
  • C语言结构体字节对齐规则

    千次阅读 2019-04-12 10:55:40
    C语言结构体字节对齐规则 基本规则 规则1 :结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在32位机为4字节,则要从4的...
  • C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。结构体到底怎样对齐?下面总结了对齐原则,在没有#pragma pack宏的情况下: 原则1、普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后...
  • 1. 结构体内存对齐规则   对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值   vs中的默认值为8; Linux中的默认值为4; 原则1:数据成员的对齐规则(以最大的类型字节为单位)。   结构体(struct)的...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 278
精华内容 111
关键字:

c语言结构体对齐规则

c语言 订阅