精华内容
下载资源
问答
  • 2019独角兽企业重金招聘Python工程师标准>>> ...

    前不久,在C++程序中碰到一个有关结构体字节对齐的问题。

    一。问题描述

    在程序中,定义了一个结构体,如下:
    typedef struct
    {
       char name[33];
       int ID;
       int  age;
    } PERSON;

    声明了一个该结构体的数组:
    PERSON peo[30];

    当从结构体中取出ID字段给一个int类型的局部变量赋值时,却出现异常.
    比如结构体中的字段都已经有初始值
    peo[0].ID =4;

    下面的赋值语句
    int tempID = peo[0].ID;
    却不能正确得到数值4,tempID得到的是67108864.
    经检查67108864是4在高位时的数值大小.
    赋值时本来应该是取内存中的四个Bytes:"04 00 00 00"
    可是取值时却是用"00 00 00 04" 的方式.
    在调试过程中,从peo[0].ID取值是正确的,得到数字4,可程序执行上面赋值语句后:
    tempID还是得到的是67108864.

    也就是说,在调试器中取值是正确的,汇编后的程序取值却是不正确的.
    程序在开始用了的很长一段时间并没有出现这种问题,这个问题是最近才发生的.
    真是百思不得其解。还有一点是明确的,程序涉及到网络传输。

    可是如果把结构体中的字符数组大小由33改为36,一切正常了!

    原理上肯定是结构体的位对齐问题,但为什么以前编译使用没出问题,现在编译才发生呢?
    应该怎么解决呢?

    二。寻找问题的原因。

    经过CSDN社区各位老大的帮助,并且自己仔细去了解程序中的编译条件部分,原则上理解了这问题的本质所在。

    发现在网络模块中使用到了"#pram pack(1)"这样的编译条件,而其它模块则没有加入这种编译条件。

    而CSDN中其中一个大虾是这样解释的:“对齐方式是给编译器看的,编译器根据这个来决定内存布局。一旦编译成二进制文件内存布局就已经确定了,如果两段代码对同一个结构使用的对齐方式不同,那么就会对内存里的值做出了不同的解释,赋值的一方认为char[33]占了36个字节,从第37个字节填写04 00 00 00,可是读取的一方认为char[33]只有33个字节,那就从第34个字节处取四个字节当作ID。”

    这次网友的解释,我认为指出了问题的本质所在:“如果两段代码对同一个结构使用的对齐方式不同,那么就会对内存里的值做出了不同的解释”。我们的程序给结构体初始化部分是按VC编译器中默认的结构体8字节对齐,而在网络模块中,由于使用了"#pram pack(1)",结果从结构体中取值时,编译器认为结构体是按1字节对齐,最终导致了问题的产生。

    三。解决方法

    为了解决这个问题,就需要程序中所有的代码对同一个结构体都使用同一种对齐即可。

    会有两种解决办法:
    一是把网络模块中的"#pram pack(1)"去掉,结构体都是按VC编译器中默认的结构体8字节方式对齐。
    二是设置结构体按1字节方式进行对齐,程序所有模块都按这种对齐方式编译。

    设置在VC的"project"->"setting..."->"c/c++":struct member aligment改成1 Bytes.

    转载于:https://my.oschina.net/u/1024767/blog/746369

    展开全文
  • // 0x00, //字节对齐填充 DISPLAY_NORMAL, // 01 Display POWER_NORMAL, // 01 Power 0x0a,0x00, // 02 Sample Interval 0x3c,0x00,0x00,0x00, // 04 Record Interval 0x00,...
  • Pack=1 默认的8字节为一个对齐单位Pack=4 4字节对齐的意思是4字节为一个对齐单位Pack=1 1字节对齐的意思就是连续存放 一、对齐长度 如果没有显式的指定对齐长度,将以结构中占用空间最大的成员的长度作为对齐长度;...

    一、在struct等结构的对齐上面应用

    Pack=1 默认的8字节为一个对齐单位
    Pack=4 4字节对齐的意思是4字节为一个对齐单位
    Pack=1 1字节对齐的意思就是连续存放

    一、对齐长度

    如果没有显式的指定对齐长度,将以结构中占用空间最大的成员的长度作为对齐长度;如果要显式指定对齐长度,需设置StructLayoutAttribute.Pack,如:

    对齐长度的作用在于:如果某个字段的长度大于或等于对齐长度,则对齐长度没用;如果小于对齐长度,则以对齐长度为单元,占用的空间是对齐长度的整数倍,同时保证不大于对齐长度的字段一定分配在同一单元,并且其首地址一定是字段长度的整数倍。

    字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

    展开全文
  • 本文主要针对结构体内存对齐python Struct,以及二进制文件解析做总结。 一、结构体内存对齐 1、为什么要内存对齐 (1)平台移植性好 不是所有硬件平台都能访问任意地址上的数据,某些硬件平台只能在某些地址...

    本文主要针对结构体内存对齐,python Struct,以及二进制文件解析做总结。

    一、结构体内存对齐

    1、为什么要内存对齐

    (1)平台移植性好

    不是所有硬件平台都能访问任意地址上的数据,某些硬件平台只能在某些地址访问某些特定类型的数据,否在抛出硬件异常,即遇到未对齐的边界值就直接不进行读取数据了。

    (2)cpu处理效率高

    用空间换取时间,提高效率。

    举个例子:如下结构体,cpu对齐单位4

    如果不对齐,读取字节的方式如下,会读取3个周期

    如果字节对齐,一共读取2个周期,如下:

    2、结构体怎么对齐的?

    (1)对齐规则

    第一个成员在与结构体变量偏移量为0的地址

    对齐数=编译器默认的一个对齐数与该成员大小的较小值

    下一个成员存放的起点,必须是该成员大小的整数倍

    linux中默认为4,vs中默认值为8

    结构体总大小为对齐数的整数倍(每个成员变量,除了第一个,都有一个对齐数,该对齐数为其中最大的一个)

    (2)举例说明:

    例子1:

    例子2:

    二、python struct

    1、struct函数

    struct 模块中最重要的三个函数,pack(),unpack(),calcsize()

    (1)按照给定的格式化字符串,把数据封装成字符串(类似于C结构体的字节流)

    string = struct.pack(fmt, v1, v2, ...)

    (2)按照给定的格式(fmt)解析字节流string,返回解析出来的tuple

    tuple = unpack(fmt, string)

    (3)计算给定的格式(fmt)占用多少字节的内存

    offset = calcsize(fmt)

    2、struct 中的格式化字符串

    (1)struct 中支持的格式如下表:

    (2)为了同c中的结构体交换数据,还要考虑有的C或C++编译使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换,可以用格式中的第一个字符来改变对齐方式,定义如下:

    (3)举个例子:

    三、二进制文件解析

    1、解析C语言生成的二进制文件思路:

    (1)以二进制文件读取文件

    (2)二进制文件一般由文件头+内容(数据块组成),一般解析内容

    (3)根据原生文件的结构体进行解析

    (4)获取文件大小,再减去头部,根据每个数据块的大小,计算循环读取次数

    2、写CSV文件

    struct unpack解析出来的数据是元组格式,需要转换为list,方便写入csv文件

     

    展开全文
  • from ctypes import * class ProtocolToPLC... _pack_ = 1 # 1字节对齐 _fields_ =[('head0', c_uint8, 2), # 相当于c 中的 uint8_t :2 ('head1', c_uint8, 6), # 相当于c 中的 uint8_t :6 ('seq',
    from ctypes import *
    
    
    class ProtocolToPLC(BigEndianStructure): # 大端模式 ,小端模式就是LittleEndianStructure
        _pack_ = 1 # 1字节对齐
        _fields_ =[('head0', c_uint8, 2), # 相当于c 中的 uint8_t :2
        			('head1', c_uint8, 6), # 相当于c 中的 uint8_t :6
                    ('seq', c_uint16),
                    ('year', c_ubyte),
                    ('month', c_ubyte),
                    ('day', c_ubyte)]
    
    # 求字节数
    sizeof()
    
    # 按字节填充结构体
    test = ProtocolToPLC()
    memmove(addressof(test), data, sizeof(test))
    
    展开全文
  • VC2005中,结构体字节对齐: #param pack(x) //开始按照指定对齐 struct { ....... } #param pack() //取消对齐 管理员在2009年8月13日编辑了该文章文章。 --> -->
  • 我们这样把这个结构体(暂且认为是结构体吧)打包成字节流:    我这样打包,直接发送出去,字节数为 1(字符/char)*4 + 4(int) *17 = 32 位。用c++/c#接收,没有什么问题的。 但是接收的时候,出现无法...
  • 结构体内存对齐

    多人点赞 2021-03-20 00:26:50
    结构体内存对齐 前言 在C语言中,除了最常见用数据类型,字符类型(char)、整数类型(short、int、long )、实型(float、double),,,,,,最常见也是最经典的还有一种数据类型,那就是结构体。 那么结构体的大小该...
  • 因为结构体内存对齐问题算是面试或笔试时的常考问题,所以我选择单独开一篇来讲解一下!!! 这个问题我当时是有点懵逼的在看到的时候,不知道是怎么计算出来的。 终于经过一段时间我仔细看了计算规则和理解我算是弄...
  • 而不要过多使用复杂结构体传递数据,因为 C 语言的结构体中,每个成员会执行对齐操作与前一个成员保持字节对齐,也就是说,成员的书写顺序会影响结构体占用的空间大小,因此会在 Java 端定义结构体时会造成不小的...
  • 一,什么是对齐  1,现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问都可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问。  2,所以这就需要各类型...
  • C/C++ 结构体内存对齐

    2014-03-31 00:32:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 目前通过c++程序生成的文件,需要python读取出数据。但发现直接按字段类型读取,会提示指定buf长度与格式串不匹配,需要...这个结构体计算需要100字节,实际c++程序中显示sizeof()是104字节。根据python文档描述,说..
  • 结构体的声明 struct Stu { char name[20];//名字 int age;//年龄 char sex[5];//性别 char id[20];//学号 };//分号不能丢 //特殊的声明 //匿名结构体类型 在声明的时候省略掉了结构体标签(tag) struct { ...
  • Python: struct 模块之字节对齐问题

    千次阅读 2019-04-21 19:22:08
    PythonPythonPython 在二进制写文件时,可以用 structstructstruct 模块将数据捆绑成结构体转化成字节流,为了方便与 CCC 交互,避免 CCC 在读取二进制字节流时因为 CCC 的字节对齐问题而造成不必要的麻烦,...
  • python与C结构体之间数据转换前言在实际应用中,可能会遇到直接和C进行二进制字节流协议通信,这时要把数据解包成python数据,如果可能,最好与C定义的结构体完全对应上.python中有2种方式,可处理二进制数据转换用ctypes...
  • python struct 结构体

    万次阅读 多人点赞 2018-07-12 20:44:57
    import struct 有的时候需要用python处理二...可以用 struct来处理c语言中的结构体. struct模块中最重要的三个函数是pack(), unpack(), calcsize() pack(fmt, v1, v2, ...) 按照给定的格式(fmt),把数据封装成字...
  • sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 (二)使用方法 1、用于数据类型 sizeof使用形式:sizeof(typ...
  • 结构体对齐的,而且windows跟linux也不一样,平常不注意的话,会导致莫名其妙的问题 最近在找一个离奇的问题,最终虽然找到是强制转换导致问题,但实际上还是结构体对齐问题跟协议设计问题 背景: 某端口收到一帧...
  • Python进阶篇-struct字节对齐问题Python进阶篇-struct字节对齐问题Python调用C的时候,会传递一些复杂的数据结构,例如结构体,这时候就会遇到各种各样字节对齐的问题。下边所有的例子都是在windows 64bit下的结果。...
  • python实现结构体数组

    千次阅读 2019-09-20 12:55:19
    结构体数组 在C语言中我们可以通过struct关键字定义结构类型,结构中的字段占据连续的内存空间,每个结构体占用的内存大小都相同,因此可以很容易地定义结构数组。和C语言一样,在NumPy中也很容易对这种结构数组进行...
  • 参考链接: Python中的struct模块 P y t h o n Python Python 在二进制写文件时,可以用 ...
  • 结构体对齐详解

    2013-02-25 12:53:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 前言字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?本文将简单理一理字节对齐的那...
  • 结构体数组 在C语言中我们可以通过struct关键字定义结构类型,结构中的字段占据连续的内存空间,每个结构体占用的内存大小都相同,因此可以很容易地定义结构数组。和C语言一样,在NumPy中也很容易对这种结构数组进行...
  • python和c通过socket进行数据传输时,会用到pack和unpack包来进行数据的打包和解包,对于不同类型的数据往往会存在一个“字节对齐”问题: struct.error: unpack requires a buffer of 35 bytes 比如在一字节Byte...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,111
精华内容 844
关键字:

python结构体字节对齐

python 订阅