如何使 C++ class 在内存中具有特定大小

How to make C++ class have specific size in memory

我得到了一个用于 IO 操作的 C++ 框架(我无法更改),其工作方式如下:

struct Operation {
   size_t block;  // index of external memory block
   void * data;   // here the data will be written or read from
}

实际读取或写入是这样的:

Operation o; 
o.block = 42; // index of block i want to read from
o.data = // where i want the data to end up
io.read(o);

问题是 read/write 是用 memcpy 实现的,它总是移动 block_size 字节的块。但是,当我想将 class X 保存并加载到此外部存储器时,我遇到了问题,因为可能 sizeof(X) != block_size

所以我什么时候会这样做:

X x;
Operation o; 
o.block = 42; // index of block i want to read from
o.data = &x;
io.read(o);

io.write(o);

如果sizeof(X) < block_size 我在读取过程中遇到问题,因为将读取比我想要的更多的字节,可能会损坏堆栈。 如果 sizeof(X) > block_size 我在写入过程中遇到问题,因为并不是 X 的每个字节都会被写入,所以我对它的备份不完整。

我想将每个块用于 X 的一个实例,我可以确保 sizeof(X) < block_size。有什么方法可以将一些填充字节添加到 X,所以它恰好有 block_size 个字节?

X x;
Operation o; 
o.block = 42; // index of block i want to read from
o.data = &x;
io.read(o);

好吧,正如您自己所说,您不能那样做。你必须指向一个block_size块,然后复制到相关的class:

BYTE buffer[block_size];
X x;
Operation o; 
o.block = 42; // index of block i want to write to
o.data = buffer;
io.read(o);
memcpy(&x, buffer, sizeof(X));

写入同上(您不能简单地写入 X 末尾之后的任何内容,因为您可能会掉下悬崖进入未映射的页面):

BYTE buffer[block_size];
X x;
Operation o; 
o.block = 42; // index of block i want to read from
o.data = buffer;
memcpy(buffer, &x, sizeof(X));
io.write(o);

我不会评论界面本身的完整性。和 static_assert(sizeof(X) <= block_size)。并且 X 类型必须是 memcopy 安全的。

书中还有更多技巧,比如让 sizeof(X) 始终匹配 block_size(通过填充)或使用分配技巧(始终在 block_size 区域分配 X,永远不要使用在堆栈上)。但是在 write/after 读取之前复制是最简单、最不棘手的。