我想直接将memcpy放入一个结构体中,但没有一个方法能正确避免padding的问题

问题描述 投票:0回答:1

我试图打开一个二进制文件,并从中读取头文件。我可以用一系列的整数来读取它,但我决定把它转换成一个结构,以允许n个对象的数量。然而,我每次都会遇到不同的问题,这些问题都是关于结构体引入的填充。

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

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

当我尝试

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

我遇到了一个问题,即sizeof(info)返回的大小比第一个结构体大得多。我想试试pragma pack,但我想要一个不依赖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);
c++ c++11 memcpy
1个回答
5
投票

结构的布局总是依赖于编译器,没有任何通用的方法来强制采用特定的布局。 大多数编译器都有某种 pack 指令,无论是通过 #pragma__attribute__ 或其他的东西,但是没有一种方法可以适用于所有的编译器。

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

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()的很好。

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

© www.soinside.com 2019 - 2024. All rights reserved.