将一个int结构转换为一个int数组

时间:2011-03-21 17:22:50

标签: c arrays struct

我正在使用一个具有一个带结构数组的函数的库。该结构和函数具有以下布局:

struct TwoInt32s
{
  int32_t a;
  int32_t b;
};

void write(struct TwoInt32s *buffer, int len);

我的初步测试表明,这样的结构数组与int32_t的数组具有相同的内存布局,所以我可以这样做:

int32_t *buffer = malloc(2 * len * sizeof(int32_t));
/* fill in the buffer */
write((struct TwoInt32s*)buffer, len);

但是我想知道这是否普遍存在。使用int32_t数组大大简化了我的代码。

编辑:我忘记了尺寸

根据我的阅读,C保证了一些关于struct padding的东西:

  1. 会员不会重新订购
  2. 仅在具有不同路线的成员之间或在结构
  3. 的末尾添加填充
  4. 指向结构的指针指向与指向其第一个成员的指针相同的内存位置
  5. 每个成员以适合其类型的方式对齐
  6. 结构中可能存在未命名的孔以实现对齐
  7. 由此我可以推断ab之间没有填充。但是结构可能最后会有填充。我对此表示怀疑,因为它在32位和64位系统上都是字对齐的。有没有人有这方面的其他信息?

4 个答案:

答案 0 :(得分:10)

实现可以自由填充结构 - ab之间可能有未使用的字节。保证第一个成员不会从结构的开头偏移。

通常,您使用特定于编译器的编译指示来管理此类布局,例如:

#pragma pack(push)
#pragma pack(1)
struct TwoInt32s
{
  int32_t a;
  int32_t b;
};
#pragma pack(pop)

答案 1 :(得分:3)

malloc分配字节。你为什么选择“2 * len”?

你可以简单地使用“sizeof”:

int32_t *buffer = malloc(len * sizeof(TwoInt32s));
/* fill in the buffer */
write((struct TwoInt32s*)buffer, len);

正如Erik所说,打包结构是一个好习惯。

答案 2 :(得分:2)

最不安全,但转换 - 即创建一个新数组并用结构中找到的值填充它,然后终止结构。

答案 3 :(得分:0)

您可以分配结构,但将其成员视为一种虚拟数组:

struct TwoInt32s *buffer = malloc(len * sizeof *buffer);

#define BUFFER(i) (*((i)%2 ? &buffer[(i)/2].b : &buffer[(i)/2].a))

/* fill in the buffer, e.g. */
for (int i = 0; i < len * 2; i++)
    BUFFER(i) = i;

不幸的是,GCC和Clang目前都没有“获得”此代码。