Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C __属性__((压缩))对嵌套结构数组的影响? 问题_C_Arrays_Gcc_Attributes_Struct - Fatal编程技术网

C __属性__((压缩))对嵌套结构数组的影响? 问题

C __属性__((压缩))对嵌套结构数组的影响? 问题,c,arrays,gcc,attributes,struct,C,Arrays,Gcc,Attributes,Struct,我正在努力通过网络将原始结构发送到另一端的已知程序,但不得不担心用于对齐结构的静默引入的内存(还包括了endianness等其他问题)。我的工作是这样的: typedef struct __attribute__((packed)) { uint16_t field1; uint16_t field2; uint16_t field3; } packed_1_s; typedef struct __attribute__((packed)) { uint16_t fie

我正在努力通过网络将原始结构发送到另一端的已知程序,但不得不担心用于对齐结构的静默引入的内存(还包括了endianness等其他问题)。我的工作是这样的:

typedef struct __attribute__((packed))
{
   uint16_t field1;
   uint16_t field2;
   uint16_t field3;
} packed_1_s;

typedef struct __attribute__((packed))
{
   uint16_t fieldA;
   uint16_t fieldB;
   packed_1_s structArray[10];
} packed_2_s;

typedef struct __attribute__((packed))
{
   uint16_t fieldX;
   packed_2_s fieldY;
   uint8_t arrayZ[20];
} data_s;
我理解,通常情况下,压缩的结构可以/将为结构的每个实例分配额外的空间,以将其填充到编译器喜欢的大小(取决于为其构建的硬件),并且喜欢的大小可以是2字节到64字节(最近)。通常情况下,如果我在packed_2_中有一个packed_1_的实例,就不会有问题,但我知道当你尝试将元素放入数组时,会有一些不同

尝试的解决方案 gcc文档似乎表明,只要在packed_2_的定义中包含packed属性,字段(即使是数组)都将尽可能紧密地打包,并且不会向packed_2_的结构中添加空间来对齐数组的元素。但是,关于align()属性的文档表明,数组的处理方式与其他字段不同,需要直接在字段上设置align/packed属性,以便修改添加的额外间距以匹配指定的对齐方式(或缺少对齐方式)。我尝试在structArray字段上设置压缩属性,但没有成功时,在上面的代码中通过在arrayZ上设置压缩属性进行了测试:

两次尝试都给了我一个编译器警告,在这个上下文中,packed属性不被理解,将被跳过(我用“-Wall”构建的好东西)

我希望解决这个问题的方法是使用属性align(1),表示所需的对齐方式为1字节,与压缩属性相当,但是文档中说align()属性只能增加对齐方式,而压缩应该用于减少对齐方式

考虑 从GCC文档中我可以确定,似乎有3种主要情况需要插入额外的内存

  • 结构内容可能有额外的内存分配给 结构自身以更改字段之间的间距。
    有效地,定义了结构的内存映射 结构中的内容可能会更改(但顺序不会更改) 元素的名称)
  • 结构可能有额外的内存分配给它们来填充 将它们转换为更有效的总体尺寸。这通常是 因此,在声明以下变量之一之后,还需要其他变量 它们的实例与 由系统/编译器定义“块”的结构实例
  • 数组,无论是否在结构中,都可能有额外的 添加内存以将元素转换为有效对齐方式
  • 就我所知,packed属性可以用来影响结构并阻止在上面的案例1和案例2中添加的额外内存,但是在我的编译器上似乎没有办法处理上面的案例3

    问题 有没有办法保证数据结构绝对没有额外的空间添加到它或它的任何子结构中,这样内存映射中就没有编译器相关的移位?我是否误解了编译器可以插入空间来有意移动内存映射的情况

    编辑 我和我当地的导师讨论了一些问题,听起来我对上面的案例3有些误解。阵列中的元素之间没有插入空间,但保证它们正确对齐的额外空间将添加到结构本身。显然,这表明“sizeof(structureOnlyContaining_uint32_t)”之类的内容不会总是返回“4”,因为可能会添加额外的空间来对齐正在使用的编译器上的uint32_t数据类型。结果只有两种情况:

  • 结构内存映射中字段之间的较大偏移量。
    可以修改字段之间的间距以对齐每个字段。 这可以使用packed或align()属性进行更改
  • 结构端垫。由返回的结构的大小 可以修改sizeof(),使结构数组结束 为系统正确对齐。这使得所有系统都可以假设 结构的起点将始终保持一致,从而引发问题 如果他们不是。这似乎不受“打包”或“对齐”属性的影响
  • 由于新的情况2,结构中数组的元素不一定遵循结构上指定的packed或align()属性,尽管数组的开头和紧跟在数组后面的字段确实如此


    然后,我的问题是如何处理packed_2_中的structArray,因为数组作为一个整体的大小不能完全由packed属性来保证。是否有某种方法可以保证structArray字段作为一个整体的固定大小?需要注意的是,我不能将压缩的大小增加太多,因为数据结构需要保持尽可能小(它在流式场景中替换音频/视频数据)。

    请注意以下关于
    \u属性((压缩))

    • 当在结构声明中使用
      packed
      时,它将压缩其字段,例如sizeof(structure)==sizeof(first_member)+……+sizeof(最后一名成员)

    • 这里,数组只是结构的一个成员。打包数组的包含结构不会更改数组的大小。事实上,(任何)数组的大小都是始终sizeof(element)*number\u个元素

    • 类似地,封装内部结构的包含结构不会改变内部结构的大小。Th
      packed_1_s structArray[10] __attribute__((packed));
      
      uint8_t arrayZ[20] __attribute__((packed));
      
      struct elem_struct {
          uint32_t x;
      } __attribute__((packed));
      // packed guarantees that sizeof(struct elem_struct) = sizeof(uint32_t) = 4
      
      struct array_struct {
          struct elem_struct arr[10];
      } __attribute__((packed));
      // packed guarantees that sizeof(struct array_struct) =
      // = sizeof(struct elem_struct[10]) = 10 * sizeof(struct elem_struct)
      // = 10 * 4 = 40