Home > Mobile >  How to write after the end of the already initialized struct?
How to write after the end of the already initialized struct?

Time:09-06

I have a struct initialized on a stack, and i want to write data in memory right after the struct and make a pointer inside a struct point to that data. I know it is achievable on the stack/heap with uninitialized structure using malloc(sizeof(struct) additional size) or alloca(). but can i perform initialization of a data after the struct is already initialized on the stack? and can i perform this initialization inside a initializator function?

Simple example:

struct TEST {
    wchar_t* itest;
};

void init_struct(struct TEST* test) {

    // point to the end of the struct
    char* walk_ptr = (char*)test   sizeof(test);
    test->itest = (wchar_t*)walk_ptr;
    
    // initialize data after the struct
    ...
}

int main(void) {
    
    struct TEST test;
    init_struct(&test);

    return 0;
}

CodePudding user response:

You could do this by embedding the structure inside another structure to reserve memory for the extra data:

int main(void)
{
    struct { struct TEST test; wchar_t data[NumberOfElements]; } S;
    init_struct(&S.test);
    …
}

However, the code in init_struct adds an incorrect size, sizeof(test), to the pointer. You likely wanted to add sizeof (struct Test), or, equivalently, sizeof *test, since you want to get past the struct TEST that test points to, not past a struct TEST * that test is.

However, even adding the correct size of the structure would not guarantee strictly conforming C code, since C implementations may insert padding between structure members. Properly we would add the offset of the data member. To do that, we nwould eed to give the structure a tag and then either make the structure definition visible to init_struct or pass the offset to init_struct. However, it is easier just to pass the address of the extra data:

void init_struct(struct TEST *test, wchar_t *data)
{
    test->itest = data;
}


int main(void)
{
    struct { struct TEST test; wchar_t data[NumberOfElements]; } S;
    init_struct(&S.test, S.data);
    …
}

Of course, a pointer can point anywhere, and there is no apparent reason the data should be immediate after the structure, so we can disconnect them:

int main(void)
{
    struct TEST test;
    wchar_t data[NumberOfElements];
    init_struct(&test, data);
    …
}
  •  Tags:  
  • c
  • Related