您好,感谢您的帮助!
我正在尝试为多种数据类型(char、int、float 等)制作通用数据缓冲区,我想知道如何使用指向缓冲区和特定位置的指针访问特定地址。
我举个例子解释一下:
1.) 假设我想将 4 个变量(int、int、char、float)保存到缓冲区
2.) 因此,此缓冲区的大小为:int size = sizeof(int)*2 + sizeof(char) + sizeof(float)
3.) 因此,缓冲区:void* buffer = malloc(size);
4.) 现在,我已经分配了缓冲区,我想将一些浮点变量写入特定位置 - 即缓冲区 + (sizeof(int)*2 + sizeof(char) ) 对吗?如何做到这一点以及是否可能...
我有解决方案,我将按照指定的方式和工作方式写入数据,但我想跳到任何位置(当然,当我知道缓冲区中某个变量的确切(地址)位置时)
所以类似的东西对我有用:
int* val1 = (int*) buffer;
*val1 = 1;
buffer = val1+1; //move pointer behind first position (+ sizeof(int))
int* val2 = (int*) buffer;
*val2 = 2;
buffer = val2+1; //move pointer behind second position (+ sizeof(int))
char* val3 = (char*) buffer;
*val3 = 'a';
buffer = val+1; //move pointer behind third position (+ sizeof(char))
float* val4 = (float*) buffer;
*val4 = 11.4;
--> 所有数据都正确保存在缓冲区中
但我更感兴趣,如果有可能(以及如何)跳转并在第 4 个位置写入 first float(不要忘记 before 是 int、int、char)
因为我不能使用类似的东西:
float* val4 = (float*) buffer + 4; // value 4 has address buffer + sizeof(float)*4 and I need address buffer + sizeof(int)*2 + sizeof(char)
很抱歉解释这么慢,但我想确定,我需要解决的问题真的很明显。非常感谢您的帮助!
p.s:我脑子里只有一个带有 (char*) 缓冲区的解决方案(因为在每个平台上都应该是 sizeof(char) == 1 ....但我不确定这是否真的是保存选项)
之后:
char* pointerOnVal4 = (char*) buffer + sizeof(int)*2 + sizeof(char);
float* val4 = (float*) pointerOnFloat;`
最佳答案
从您描述问题的方式来看,您想要:
struct Foo
{
int a, b;
char c;
float f;
};
但是如果你真的需要动态地做它(我不确定你为什么会这样做),你会写这样的东西:
struct Type
{
size_t align;
size_t size;
};
struct Field
{
Type *type;
size_t offset;
};
class ObjectType
{
private:
std::vector<Field> fields;
public:
void add_field(Type *t)
{
size_t off = fields.empty() ? 0 : fields.back().offset + fields.back.type->size;
if (off % t->align)
off += t->align - off % t->align;
fields.push_back({t, off});
}
};
...然后在 uint8_t 数组上使用 ObjectType
请注意,类型的大小和对齐之间没有一般关系,除了大小必须是对齐的倍数。例如,在某些系统上,long double 具有对齐 4 和大小 12(但仅使用 10 个字节用于重要数据,2 个字节用于填充)。
也就是说,如果您希望它在平台之间兼容(例如,跨网络,以及同一主机上的 32 位和 64 位代码),您需要做的远不止这些。
关于C++ 访问 void* 中的特定地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23850965/