首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【烧脑技术贴】无法回避的字节对齐问题,从八个方向深入探讨(变量对齐,栈对齐,DMA对齐,结构体成对齐,Cache, RTOS双堆栈等)

四、结构体成员对齐问题: 首先明白一点,结构体里面的变量是什么类型,此变量的位置就是至少要几字节对齐,所以就存在结构体实际占用大小不是这些变量之和。...,b占用2字节对齐,c需要4字节对齐,这样就空出来2两个字节未使用,d占用8字节,最后一个a占用了8字节。...比如我们设置的8字节对齐,那么中断发生的时候,如果SP指针位置在4字节对齐,那么硬件自动插入4字节来保证8字节对齐,之后就是硬件自动入栈的寄存器开始存入栈中。...七、硬件浮点对齐问题 如果使用的是带FPU硬件浮点单元的M内核芯片就要注意对齐访问了,访问单精度浮点数访问一定要4字节对齐,双精度要8字节对齐。...这个问题的关键就是M7的TRM中这句话: 意思是,如果用户使用MPU将H7的AXI总线下的内存空间配置为Device 或者 Strongly-ordered模式,用户采用非对齐方式访问,将会触发UsageFault

1.4K30
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    逆向初级-PE(五)

    SizeOfUninitializedData; // 未初始化数据的节的总大小 文件对齐后的大小 编译器填写的,无用处 DWORD AddressOfEntryPoint; //...2、扩大节的步骤 分配一块新的空间,大小为S 将最后-一个节的SizeOfRawData和VirtualSize改成N N = (SizeOfRawData或者VirtualSize内存对齐后的值...个字节复制粘贴到新增加的节,然后修改新增加节的成员属性 前8个字节是节的名字:随便改个名字 把之前最后一个节的VirtualSize(内存中没有对齐的实际值)改为内存对齐后的值 改为8000...1000h字节 5.11.导出表 1、如何查找导出表 扩展PE头最后一个成员是一个数组(包含16和元素),每个数组对应一个表(每个表占8字节),如导出表、导入表等。...定位导入表 导入表位置,数组DataDirectory[1] 第一个导入表开始的位置:22A10 2、导入表结构 typedef struct _IMAGE_IMPORT_DESCRIPTOR

    1.3K30

    理解内存对齐

    在计算机体系结构中,访问未对齐的内存地址可能导致性能问题或者硬件异常,因此对齐是一种重要的优化手段。 计算机体系结构通常要求不同类型的数据在内存中的起始地址必须是某个特定值的整数倍。...在计算机体系结构中,访问未对齐的内存地址可能导致性能下降,甚至在某些体系结构上引发硬件异常。...在某些体系结构上,对齐的内存访问可以保证在单个总线事务中完成,而未对齐的内存访问可能需要多次总线事务,增加了访问的复杂性和开销。 硬件对齐限制: 一些硬件设备对数据的对齐有严格的限制。...数组对齐规则: 数组的对齐要求通常受到数组元素的对齐要求的影响。例如,如果数组中的元素要求8字节对齐,那么整个数组也需要8字节对齐。 指针对齐规则: 指针的对齐要求通常与其指向的数据类型相关。...变量对齐:对于单个变量,可以使用 alignas 关键字来指定其对齐方式。 alignas(16) int myVariable; // 将 myVariable 对齐到16字节边界 3.

    37610

    结构体内存对齐解析

    性能原因:如果数据存放在未对齐的内存空间中,则处理器在访问变量时要做两次次内存访问,而对齐的内存访问只需要一次。 上述两个原因,第一个原因从字面意思上就能够理解,那第二个原因是什么意思呢?...对比内存对齐和内存没有对齐两种情况我们可以明显地看到:在内存对齐的情况下,只需要两个个步骤就可以将数据读出来,首先处理器找到要读出变量所在的地址,然后将数据读出来。...由于此时内存未对齐,处理器是 32 位的,一次性读取或者写入都是 4 字节,所以需要将 0-3 地址内的数据和 4-7 地址里的数据都取出来。...,如果不考虑结构体本身的对齐,按照数组元素是紧挨着存放的原则,那这个结构体数组应该是按照下图进行存储的: ?...“对齐系数”和“最大数据长度”中较小值的整数倍,来对结构体本身进行对齐,因此正确的结构体数组的存储位置应该如下图所示: ?

    59010

    Redis SDS

    // 存储字符串的char数组 }; 针对sdshdr数据结构本身,我们看下在执行命令时sds是如何使用的. set命令 在执行set key redis命令时,sds存储字符串的过程 1....=11 3. len字符串长度,值为5 free未使用长度,也就是这里的预分配空间长度,同样为5 sds存储字符串redis后的数据结构 strlen命令 在计算存的字符串值的长度key时,返回sdshdr...命令,在未超过预分配空间时,也只会更新buf数组值,不会做申请空间操作. 3. setbit虽然进行位操作,但也是按字节存储,本质是一样的.可以参考位域....数据结构拆分 根据存储数据的大小,记录长度的len,buf空间,将原有的数据结构细分为5种情况,分别为sdshdr5, sdshdr8, sdshdr16, sdshdr32, sdshdr64.对应存储字符串长度分别为...取消字节对齐 采用__attribute__ ((__packed__)) 让编译器取消结构体在编译过程中的优化对齐,按照实际占用字节数进行对齐,减少空间占用. 3.

    39030

    面试大全 | C语言高级部分总结

    整个结构体要对齐,因为定义结构体变量 s1 时,再定义变量 s2 时,如果 s1 没有对齐,就坑了s2,所以也要保证整个结构体对齐。 无论是按照几字节对齐,我们都可以联想到内存实际的安排。...n字节对齐整数倍,如是4字节对齐,那么最后short算成4字节 以保证整个结构体对齐。...整个结构体对齐,如2字节对齐(2的整数倍),只要是0、2、4地址就行了,如果是4字节对齐(4的整数倍),就必须是0、4地址。...(不建议使用) 如:s1占5个字节,s2占8字节(默认) #pragma pack(1) struct stu1 { (结构体本身以及变量) 对齐规则:2字节对齐(2的整数倍),只要是0、2、4地址就行了...它的作用是让整个结构体变量整体进行n字节对齐(注意是结构体变量整体n字节对齐,而不是结构体内各元素也要n字节对齐,内部元素按照默认对齐方式) 例子: struct mystruct11 {// 1字节对齐

    2K10

    【C】alignment

    内存访问粒度 如果没有深入的了解内存方面的东西, 我们可能会认为内存不过是简单的字节数组, 例如下面的形式 但是实际上, 计算机的处理器并不是以单个字节块为单位读写内存, 而是以2个,4个,8个,甚至16...或者32个字节块为单位读写内存,如下图所示 我们将处理器访问内存单元的大小叫做其内存访问的粒度....而这种地址就是所说的未对齐的地址(unaligned address)...., i占4个字节, s占两个字节, 所以mystruct的alignment值是4, 此时该结构体占12个字节, 下面是示意图 我们将上面的结构修改一下, 将s和i的顺序换一下 struct mystruct...() // 取消指定对齐, 采用默认对齐方式 #pragma pack(1)将结构体及其成员的对齐值设为1, 也就是说结构体中的成员可以从任意的地址位置开始, 此时mystruct的大小为7.

    36820

    Java虚拟机中对象内存的分配情况

    (轻量级锁定,重量级锁定,GC标记,可偏向)对象的存储内容如下: 存储内容 标志位 状态 对象哈希码,对象分代年龄 01 未锁定 指向锁记录的指针 00 轻量级锁定 指向重量级锁的指针 10 膨胀(重量级锁定...如果对象是一个Java数组,在对象头中还须有一块用于记录数组长度的数据,因为虚拟机可通过普通Java对象的元数据信息确定Java对象的大小,但从数组的元数据中无法确定数组的大小。...对象头部分是 8 字节的倍数,所以当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。...对象大小估算   32 位系统下,当使用 new Object() 时,JVM 将会分配 8(Mark Word+类型指针) 字节的空间,128 个 Object 对象将占用 1KB 的空间。...此时对象的结构示意图,如下图所示: ? 参考资料:

    77340

    C语言黑魔法第三弹——动态内存管理

    本文由于排版问题,可能稍显枯燥,但里面知识点非常详细,建议耐心阅读,帮助你更好的理解动态内存管理这一C语言大杀器 进阶C语言中有三个知识点尤为重要:指针、结构体、动态内存管理,这三个知识点决定了我们之后学习数据结构是否顺利...首先,我们先来看一下动态开辟的空间在内存中的分布,感受一下其中的魅力: 一、为什么存在动态内存分配 int arr[20]={0}; 比如上面这个数组,我们申请了80个字节的空间,能够存放20个整型数组...在分配内存时,要考虑到内存对齐的问题,避免因内存对齐导致的性能损失。...释放内存空间后,应该将指针设置为NULL,以避免出现野指针的情况。 释放已经释放过的内存空间会导致未定义的行为,因此应该避免重复释放同一块内存空间。...如果realloc函数无法在原地重新分配内存空间,将会在另一块内存空间中重新分配,并将原数据复制到新内存空间中。因此,重新分配可能会比较耗时。

    10110

    【深入解读Redis系列】(五)Redis中String的认知误区,详解String数据类型

    char buf[];     // 字符串的实际内容 字节数组,保存实际数据。为了表示字节数组的结束,Redis 会自动在数组最后加一个“\0”,这就会额外占用 1 个字节的开销。...对于小于等于44字节的字符串,将元数据、指针和SDS布局在一起,避免了内存碎片。而对于大于44字节的字符串,将SDS分配独立的空间,并使用指针指向SDS结构,避免了内存浪费。...在这个场景中,dictEntry 结构占用了 24 字节的空间,不是 32 字节。这是因为 jemalloc 对申请的内存进行了对齐,使得 dictEntry 结构的起始地址对齐到 8 字节的边界。...这是因为图片 ID 和图片存储对象 ID 的总长度为 16 字节,而 jemalloc 会按照对齐的原则,将内存地址对齐到 8 字节的边界。...对齐是为了提高内存访问的效率,因为现代计算机的内存访问通常是按照字节对齐的方式进行的。对齐的规则通常是按照数据类型的大小进行对齐,比如 1 字节对齐、2 字节对齐、4 字节对齐等。

    55070

    【C++指南】C++中的内存对齐规则及原因详解

    C++作为一种底层抽象程度较高的编程语言,允许开发者通过编译器选项或特定语法来控制数据的内存布局,以满足这些硬件需求。 本文将详细介绍C++中的内存对齐规则及其背后的原理。...优化内存带宽利用:内存带宽是有限的,对齐数据可以减少因读取未对齐数据而产生的额外开销,使内存带宽得到更有效的利用。...例如,int类型(假设为4字节)应该至少4字节对齐,而double类型(假设为8字节)则应8字节对齐。 具体规则如下: 第⼀个成员在与结构体偏移量为0的地址处。...结构体和类:对于复合类型,如结构体或类,其成员变量的对齐方式取决于各自的基本类型。结构体或类的整体对齐要求是其所有成员中最大的对齐要求。 数组:数组的对齐方式与其元素类型相同。...Padding (6 bytes):为了使整个结构体的大小是8字节的倍数,插入6字节的填充。 结语 C++中的内存对齐是一个复杂但至关重要的概念。

    18810

    嵌入式笔试面试题目系列(二)

    2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。...结构体struct内存对齐的3大规则: 1.对于结构体的各个成员,第一个成员的偏移量是0,排列在后面的成员其当前偏移量必须是当前成员类型的整数倍; 2.结构体内所有数据成员各自内存对齐后,结构体本身还要进行一次内存对齐...(说明:按几字节对齐,是根据结构体的最长类型决定的,这里是int是最长的字节,所以按4字节对齐); 2.使用64位编译 ,int占4, char 占1, unsigned short 占2,char*...占8,函数指针占8个,由于是64位编译是8字节对齐(说明:按几字节对齐,是根据结构体的最长类型决定的,这里是函数指针是最长的字节,所以按8字节对齐)所以该结构体占24个字节。...不同平台内存对齐方式不同。如果使用结构体进行平台间的通信,会有问题。例如,发送消息的平台上,结构体为24字节,接受消息的平台上,此结构体为32字节(只是随便举个例子),那么每个变量对应的值就不对了。

    71530

    【C语言基础】结构体赋值

    结构体在 C 程序中使用的较为频繁,能对数据有一定的封装的作用。对一个结构体赋值时,经常采用的方式是,分别对其成员变量赋值。那么能否将一个结构体用赋值号(“=”)直接赋值给另一个结构体呢?...foo,它有3个成员变量:int 型数据 a、int 数组 b、int 指针 c,以观察是否对不同类型的成员有不同的处理。...这样的话,rep movsd 指令的作用是,将 esi 处的7个 dword 复制到 edi 处,而 foo 结构体正好占用4*7个字节(此处没有对齐的问题)。...于是,x 的内容便被复制到了另一块相同大小的内存中,我们基本可以确定,这块空间就是 y 所占的空间。...因此,我们可以得出结论,结构体可以直接赋值,且赋值的结果是将赋值号左边的结构体中的内容原原本本的复制到赋值号右边的结构体中,并没有共用同一块内存空间。

    2.9K70

    程序员C语言快速上手——高级篇(九)

    注意,这里-52是VC编译器将未使用的字节做自动填充时所用的十进制默认值,对应的也就是我们前面章节说的16进制数0xcc,它表示这个字节没有被使用。...如下这种排列就是不合理的,导致编译器做内存对齐时,将其分成三组,每组4个字节,这使得该结构体占用的内存变成了12字节。而将int a放在第一个成员位置时,编译器内存对齐后,结构体仅占用8字节大小。...想通了这个例子,基本也就想通了结构体内存对齐来提升效率的概念。 有些善于发现问题的朋友可能会想到,在64位系统里,long类型表示8字节,那么结构体怎么进行内存对齐呢?...实际上,上面仅仅是打比方来说明问题,不同的编译器,其结构体内存对齐的规则也不尽相同,并不是简单的仅仅按照4字节来对齐。...Windows下的VC编译器,主要按照4字节或8字节来对齐,而Linux下的GCC则使用2字节或4字节来对齐,这个对齐参数被称为对齐模数。

    1.6K20

    手摸手Go 你的内存对齐了吗?

    谈到内存对齐,早年间玩Java的时候就能偶尔打打交道,为此Java8还提供了个语法糖@Contended来帮助我们解决高速缓存cacheline内存未对齐的伪共享问题。...不过有些语言倒是会自动帮开发人员解决对齐问题,比如Rust最近还比较火,Microsoft也宣布将逐渐从C/C++转移到Rust构建他的基础结构软件。嗯。。。今年也立个flag 学习下。...在这种情况下,字节是存储器访问的最小单元,即每个存储器地址指定一个不同的字节。当使用二进制表示时,一个n字节对齐的地址将具有最少log2(n)个最低位有效零。 为什么要内存对齐?...零大小字段对齐 如果结构体或数组类型不包含大小大于零的字段或元素,那么它的大小就为0。...意思是开辟的结构体、数组和切片值中的第一个(64位)字可以被认为是8字节对齐的。

    55321

    JVM中 对象的内存布局 以及 实例分析

    对象内存结构 在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为3块区域: ① 对象头(Header) ② 实例数据(Instance Data) ③ 对齐填充 (Padding) 对象头...32位和64位的虚拟机(未开启压缩指针)中分别为32bit 和64bit。...对象头信息是与对象定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的信息,它会根据对象的状态复用自己的存储空间。...标志位“01”就被复用了,根据不同的状态:“未锁定” or “可偏向” 来确定“01”存储所表示的内容。...对象占用内存大小 上面我们已经对对象在内存的布局有了一点你的了解,接下来我们来看看对象占用内存的大小。也就是对象内存结构的每个部分分别占用多少的内存。

    1.2K80

    【AI系统】布局转换原理与算法

    接下来,我们将简单介绍数据布局转换,包括数据在内存如何排布,张量数据在内存中如何排布,以及数组维度排列的具体应用如 NCHW 与 NHWC 这两种数据排布方式。...举个例子,比如 32 位系统从内存中以 4 字节为粒度进行读取,64 位系统从内存中以 8 字节为粒度进行读取,所以当在处理器上进行未对齐的地址访问时,处理器将读取多个字,还有些处理器平台不支持访问任意地址上的任意数据...详细展开来讲,以 4 字节存取粒度的处理器为例,如下图所示,我们现在要读取一个 int 变量,其有 4 个字节,假如没有内存对齐机制,将一个 int 放在地址为 1 的位置,那么我们需要读取的有地址 1234...总体上来说,如果有内存对齐,如下图所示,我们只需读取一次,而没有内存对齐机制,将导致访问请求数据所需的内存事务数增加至 2 倍。...CPU 总是以其字的大小进行内存读取,进行未对齐的内存访问时,处理器将读取多个字,需要读取变量所跨越内存的所有字,同时进行处理。将导致访问请求数据所需要的内存事务增加 2 倍。

    10810
    领券