user3672760
user3672760

Reputation: 11

C++ access to specific address in void*

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

Answers (2)

nitimalh
nitimalh

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

o11c
o11c

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

Related Questions