提问者:小点点

我想直接将memcpy添加到结构中,但是没有一个方法能够正确地避免填充问题


我正在尝试打开一个二进制文件并从中读取头。 我能够以一系列整数的形式读取它,但我决定将它转换为一个结构,以允许n个对象。 然而,我每次都面临不同的问题,它们都是关于structs引入的填充。 当我试着

struct {
int x1;
int x2;
long long x3;
long long x4;
} info;

我遇到了一个问题,x1和x2后面是大小为4的填充。

当我试着

struct {
uint32 x1;
uint32 x2;
uint64 x3;
uint64 x4;
} info;

我遇到了一个问题,sizeof(info)返回的大小比第一个结构大得多。 我想尝试pragma包,但我想要一个不依赖于Visual Studio的通用Windows解决方案。 我知道正确排序声明以避免填充,但问题是顺序很重要,因为我正在使用memcpy(&info,bytes_array,sizeof(info))读取二进制文件。

我希望得到关于如何正确完成这一任务的建议,即使这意味着我必须改变结构的外观。

我的当前代码:

unsigned int read_size = sizeof(info);
char* read_array = new char [read_size];
fin.read(read_array, read_size);

memcpy(&info, read_array, read_size);

共1个答案

匿名用户

结构的布局总是依赖于编译器,并且没有任何通用的方法来强制特定的布局。 大多数编译器都有某种pack指令,不管是通过pragma,属性还是其他方式,但是没有一种方法可以适用于所有编译器。

如果您想要一个更独立于编译器的解决方案,那么就不要复制到整个结构中; 一次做一个成员。

unsigned int read_size = 24;  // use explicit size, not sizeof(info)
char* read_array = new char [read_size];
fin.read(read_array, read_size);

info i;

memcpy(&i.x1, read_array, 4);
memcpy(&i.x2, read_array+4, 4);
memcpy(&i.x3, read_array+8, 8);
memcpy(&i.x4, read_array+16, 8);

注意,编译器应该很好地优化这些memcpy。

您需要验证所使用的类型的大小是否与二进制文件中的大小相匹配,并确保它们具有正确的字节顺序。