我有以下结构:
typdef struct {
char a[4];
int b;
char c;
int d;
} varT; // Total size is 13 bytes, without padding
显示RAM中所需的内存布局,用于类型' varT&#39 ;;
的变量这意味着在RAM中,需要以下数据布局:
从地址1000到1013(不包括1013):
[ field 'a', 4 bytes | field 'b', 4 bytes | field 'c', 1 byte | field 'd', 4 bytes ]
从地址1013到1026(不包括1026):
[ field 'a', 4 bytes | field 'b', 4 bytes | field 'c', 1 byte | field 'd', 4 bytes ], ...
但是编译器在字段c
到字段d
之间添加了3个字节的填充。
为了方便地处理存储在RAM中的这种变量,你会如何建议绕过该填充?
我想做的事情类似于以下内容:
varT var;
varT *list[5];
var.a[0] = 'A'; var.a[1] = 'B'; var.a[2] = 'C'; var.a[3] = 'D';
var.b = 9876;
var.c = 'X';
var.d = 1234;
memcpy((void*)(list), (void*)(&var), 13);
var.a[0] = 'E'; var.a[1] = 'F'; var.a[2] = 'G'; var.a[3] = 'H';
var.b = 6543;
var.c = 'V';
var.d = 8887;
memcpy((void*)(list + 13), (void*)(&var), 13);
但是由于编译器添加到结构中的填充,这是不可能的。
答案 0 :(得分:3)
我认为其中一项可以完成。
gcc
,__attribute__((packed))
,__attribute__((aligned))
一些笔记。不要使用硬编码结构大小,也不要使用sizeof
来计算此类应用程序的大小,其中您将结构复制到可用于与另一个进行通信的阵列机器通过网络或写入文件,以后可以由另一个二进制文件加载。在不同的系统上,相同的代码可以生成不同的填充,因此如您所示,从阵列中加载存储的数据,以及通过网络传输阵列,这样做真的很糟糕。这是因为通信的两个二进制文件可能具有不同的填充量,导致不同的布局,这将以非常糟糕的方式破坏事物并且通常很难调试。
另一方面,如果您只是将结构复制到结构,那么这可能会有效,但为此=
可以完成工作。
答案 1 :(得分:1)
代码应该独立于这种填充。因此,请使用sizeof(varT)
代替13
。
答案 2 :(得分:0)
为什么不写一个理智的,惯用的C代替,改变:
typedef struct {
char a[4];
int b;
char c;
int d;
} varT;
可以像这样轻松处理:
varT vlist[n];
varT x = {.a = {'A', 'B', 'C', 'D'}, .b = 9876, .c = 'X', .d = 1234};
vlist[0] = x;
struct
s 可以简单地分配给。此外,这可以避免间接错误。