0

I'm interested in how you can write data in a particular structure to a pre-allocated memory block.

The idea is to write down the render commands and then read them in a loop. The problem is that allocating and deleting memory every cycle, which is 60 times per second is bad and I want to ask how can I write and read different types of data to the buffer.

example:

struct cmd_viewport {
    int x, y, w, h;
};

struct cmd_line {
    int x0, y0, x1, y1;
    unsigned int width;
};


void* buffer_alloc(void* buffer, size_t offset, size_t size) {
    ...
}

void* buffer_get_ptr(void* buffer, size_t offset) {
    ...
}

int main(int argc, char* argv) {
    void* cmd_buffer;
    struct cmd_viewport* viewport;
    struct cmd_line* line;
    struct cmd_line* line2;

    cmd_buffer = malloc(1024);

    if (cmd_buffer == NULL) {
        return EXIT_FAILURE;
    }

    viewport = (struct cmd_viewport*)buffer_alloc(cmd_buffer, 0, sizeof(struct cmd_viewport));

    line = (struct cmd_line*)buffer_alloc(cmd_buffer, sizeof(struct cmd_viewport), sizeof(struct cmd_line));

    /* it must be a direct write to the cmd_buffer memory location */
    viewport->x = 0;
    viewport->y = 0;
    viewport->w = 800;
    viewport->h = 600;

    line->x0 = 100;
    line->y0 = 100;
    line->x1 = 300;
    line->y1 = 400;
    line->width = 2;

    line2 = (struct cmd_line*)buffer_get_ptr(cmd_buffer, sizeof(struct cmd_viewport));

    printf("line->width = %d\n", line2->width);

    free(cmd_buffer);

    return EXIT_SUCCESS;
}

How can you make a void* buffer cast from a specific offset to any data type ?

flcl8193
  • 1
  • 2
  • 2
    Please [edit] your question and copy & paste your (unfinished) code instead of describing it. – Bodo Jan 19 '23 at 16:21
  • 1
    You can allocate a big enough buffer once, with type `void*` and use that to point to any other data type. After all: `malloc()` returns a `void*` pointer. – Weather Vane Jan 19 '23 at 16:24
  • Cast to a different pointer type, then use that pointer. – user253751 Jan 19 '23 at 16:26
  • Define a `union` of all the structure types, and allocate `sizeof(that union)`. That way it will be large enough for the biggest structure. – Barmar Jan 19 '23 at 16:27
  • 1
    oh you're asking how to copy a structure to a memory block? memcpy? – user253751 Jan 19 '23 at 16:27
  • @WeatherVane, yes, but if I have a lot of different structures written in the void* buffer, how can I write them down and read them from a certain offset? – flcl8193 Jan 19 '23 at 17:32
  • By following the advice from @Barmar and using an array of `union`s. – Weather Vane Jan 19 '23 at 17:39
  • you might also want to look at https://stackoverflow.com/questions/18577404/how-can-mixed-data-types-int-float-char-etc-be-stored-in-an-array/18577481#18577481 – Barmar Jan 19 '23 at 17:41
  • @WeatherVane, i think I got what I needed just in function buffer_alloc buffer_get_ptr returning buffer + offset. That is, literally changing the address and from this address making a cast to the desired type. I suspect that there may be problems with memory alignment ... – flcl8193 Jan 19 '23 at 17:56
  • @flcl8193 Curious, why the unnecessary `(struct cmd_viewport*)` cast in `viewport = (struct cmd_viewport*)buffer_alloc(cmd_buffer, 0, sizeof(struct cmd_viewport));`? – chux - Reinstate Monica Jan 19 '23 at 22:25
  • @Ichux, I want to avoid problems with old compilers. – flcl8193 Jan 21 '23 at 18:50
  • The void* arithmetic for ansi c is a gnu extension. The problem can be solved by casting to char* void* memory; void* ptr0; void* ptr1; struct test* test0; struct test* test1; (skip alloc) ptr0 = (char*)memory; ptr1 = (char*)memory + sizeof(struct test); test0 = (struct test*)ptr0; test1 = (struct test*)ptr1; With this approach, you can allocate a piece of memory for the entire program. In any case, it is not big for me and drawing graphics on different backends is a problem. – flcl8193 Jan 21 '23 at 19:02

0 Answers0