如何使 C++ class 在内存中具有特定大小
How to make C++ class have specific size in memory
我得到了一个用于 IO 操作的 C++ 框架(我无法更改),其工作方式如下:
- 它有
block_size
,这是读取或写入的块的大小
- 每个read/write操作得到这个操作结构:
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 读取之前复制是最简单、最不棘手的。
我得到了一个用于 IO 操作的 C++ 框架(我无法更改),其工作方式如下:
- 它有
block_size
,这是读取或写入的块的大小 - 每个read/write操作得到这个操作结构:
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 读取之前复制是最简单、最不棘手的。