如何使类C++内存中具有特定大小
How to make C++ class have specific size in memory
我得到了一个用于IO操作的C++框架(我无法更改),其工作原理如下:
- 它具有
block_size
读取或写入的块的大小 - 每个读/写操作都获取此操作结构:
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);
问题是读/写是用memcpy
实现的,它总是移动block_size
字节块。但是,当我想将我的类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
块,然后复制到相关类中:
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
类型必须是内存安全的。
书中还有更多技巧,例如使sizeof(X)
始终匹配block_size
(通过填充)或使用分配技巧(始终在block_size区域中分配X,切勿在堆栈上使用)。但是写入前/读取后复制是最简单,最不棘手的。
相关文章:
- 为什么使用析构函数会使类不可复制?
- 使类在使用时调用正确的构造函数
- 如何使类论坛在 C++ 中使用字符串?
- 如何使类定义外的运算符重载优先?
- 使类模板成为其自身的朋友,以进行不同的实例化
- 如何使类函数返回数组,然后将其调用并存储在 main 中
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- 如何使类C++内存中具有特定大小
- C++:使类及其某些数据成员仅在命名空间中可用
- 如何使类的函数默认
- 什么是使类不可移动的用例(如果有的话)
- 如何使类静态变量线程安全
- 有没有办法使类成员对象的模板调用不同的构造函数?
- C++ 使类的成员变量成为子类中的专用化
- 如何在 C++ 中使类属性类型与在 C# 中一样
- 如何使类在向量内可搜索?
- 自定义类的const实例化是否也会使类中的*everything*变为常量
- 使类在流上模板化处理std::cout和std::of流
- 宏使类不可压缩
- 当类对象为常量时,使类中的shared_ptr无法更改它所指向的对象