Reputation: 11
Hello there and thank you with your help!
I am trying to make universal data buffer for multiple data type (char, int, float,...whatever) and I would like to know how access specific address with pointer to buffer and specific position.
Let me explain it on example:
1.) Let's say that I would like to save to buffer 4 variables (int, int, char, float)
2.) so, size of this buffer is: int size = sizeof(int)*2 + sizeof(char) + sizeof(float)
3.) so, buffer: void* buffer = malloc(size);
4.) Right now, I have allocate buffer and I would like to write some float variable to specific position - which is buffer + (sizeof(int)*2 + sizeof(char) ) right? How to do that and if is it possible...
I have solution that I will write data how they are specified and its working, but I would like to jump on what ever position (of course, when I know, where exactly (address) some variable is in buffer)
So something like that works to me:
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;
--> All data are saved in the buffer corectly
But I am more interesting, if is possible (and how) to jump and write first float on 4th position (dont forget that before is int, int, char)
Because I can't use something like:
float* val4 = (float*) buffer + 4; // value 4 has address buffer + sizeof(float)*4 and I need address buffer + sizeof(int)*2 + sizeof(char)
Sorry for this slow explanation, but I wanna be sure, that it's really obvious what I need to solve. Thank you very much for your help!
p.s: I have in my head just one solution with (char*) buffer (because on every platform should be sizeof(char) == 1 ....but I am not sure, if this is really save option)
so after:
char* pointerOnVal4 = (char*) buffer + sizeof(int)*2 + sizeof(char);
float* val4 = (float*) pointerOnFloat;`
Upvotes: 1
Views: 199
Reputation: 961
Like the above answer, stick to struct for this:
typedef struct Foo{
int a;
int b;
char c;
float f;
}Foo;
Foo *bar = new(struct Foo);
bar->a = 1;
bar->b = 2;
bar->c = 'a';
bar->f = 11.4;
delete(bar);
Upvotes: 0
Reputation: 16086
From the way you described the problem, you want:
struct Foo
{
int a, b;
char c;
float f;
};
But if you really need to do it dynamically (I'm not sure why you would), you would write something like:
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});
}
};
... and then use ObjectType on an array of uint8_t
Note that there is no general relation between the size and alignment of a type, except that size must be a multiple of align. For example, on some systems, long double has align 4 and size 12 (but only uses 10 bytes for significant data, and 2 bytes for padding).
That said, if you want this to be compatible between platforms (e.g. across the network, but also for 32-bit vs 64-bit code on the same host), you need to do a lot more than this.
Upvotes: 0