连续空间中复杂的结构偏移

时间:2015-11-26 20:42:34

标签: c arrays data-structures casting

我想知道是否有一个优雅的替代方案:

import os

def runUpdates():
    suPassword = input("Enter su password: ")
    su = os.system("sudo su")
    su2 = os.system(suPassword)
    return su
    return su2

显然,如果这样安装起来会更简单:

struct A{
  uint64_t w;
  uint64_t x;
  uint64_t y;
  uint64_t z;
};

struct B{
  uint32_t a;
  uint16_t b;
};

void function(uint32_t length){
 //we have one struct A at the head and multiple struct B.
 struct B *ptr = malloc (length * sizeof B + sizeof A);

 //we set random values in the head:
 struct A * tmp = (struct A*)ptr;
 tmp->w = 1000;
 tmp->x = 1200;
 tmp->y = 99;
 tmp->z = ~(0ULL);

 /*then we set the first element of type B.
  *this is where my question lies
  */
 // put the pointer at the right position:
 tmp++;
 //convert that position again:
 struct B * right_position = (struct B*)tmp;

 ...// do things with B type.

}

但我的问题更多是关于如何在不编写struct root{ struct A child1; struct B *child2; } 的情况下正确标记这些偏移的方法。

如何在不使用tmp++的情况下直接访问该阵列上的第一个B元素?

同样,这不是我在实际代码中如何做到这一点。这只是我们在这里讨论的一种艺术,如果你愿意的话:)。

3 个答案:

答案 0 :(得分:1)

也许是struct B * right_position = (struct B*)((char *)ptr + sizeof(A));。 (char *)强制转换将使计算以字节为单位执行。

答案 1 :(得分:1)

struct A *a_ptr = malloc(sizeof(struct A) + length * sizeof(struct B));
struct B *b_ptr = (struct B *)(a_ptr + 1);

答案 2 :(得分:0)

也许您应该使用灵活的数组成员创建结构类型:

struct Both
{
    struct A a;
    struct B b[];
};

struct Both *c = malloc(sizeof(*c) + length * sizeof(c->b[0]));

c->a.w = 1000;
c->a.x = 1200;
c->a.y = 99;
c->a.z = ~(0ULL);

c->b[0].a = 37;
c->b[0].b = 59;

这可以保证对齐,不需要任何铸造或其他诡计。它是C99和C11的一部分,取代了struct hack。标准(ISO / IEC 9899:2011)说:

  

§6.7.2.1结构和联合说明符

     

¶18作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员。在大多数情况下,将忽略灵活数组成员。特别地,结构的尺寸好像省略了柔性阵列构件,除了它可以具有比省略意味着更多的拖尾填充。但是,当.(或->)运算符具有左操作数(指向)具有灵活数组成员且右操作数命名该成员的结构时,其行为就像该成员一样用最长的阵列替换(使用相同的阵列)   元素类型)不会使结构大于被访问的对象;数组的偏移量应保持为灵活数组成员的偏移量,即使这与替换数组的偏移量不同。如果此数组没有元素,则其行为就好像它有一个元素,但如果尝试访问该元素或生成一个超过它的指针,则行为是未定义的。

该标准随后有第20-25段,其中的示例讨论了使用柔性阵列成员的各个方面。