How to apply structure offset?

I have a structure

typedef struct foo { int lengthOfArray1; int lengthOfArray2; int* array1; int* array2; } foo; 

I need to allocate enough memory for the whole structure and its contents of the array. Therefore, assuming that each array was 5 ...

 foo* bar = (foo*)malloc(sizeof(foo) + (sizeof(int) * 5) + (sizeof(int) * 5)); 

Now I have to point array1 and array2 to the correct location in the allocated buffer:

 bar->array1 = (int*)(&bar->lengthOfArray2 + sizeof(int)); bar->array2 = (int*)(bar->array1 + lengthOfArray2); 

Is it correct?

Edit # 1

Just to eliminate any confusion: I'm trying to save memory in one block, not three.

Edit # 2

I cannot use C99 because the MSVC 2010 compiler does not support it (http://stackoverflow.com/questions/6688895/does-microsoft-visual-studio-2010-supports-c99).

+4
source share
3 answers

Following the OP approach, this should complete the task:

 /* Defining these types allows to change the types without having the need to modify the code. */ typedef int Foo_ArrayElement1_t; typedef int Foo_ArrayElement2_t; typedef struct Foo_s { size_t lengthOfArray1; /* 'size_t' is the type of choice for array/memory dimensions. */ size_t lengthOfArray2; Foo_ArrayElement1_t * array1; Foo_ArrayElement2_t * array2; } Foo_t; /* * Allocates memory to hold a structure of type Foo_t including size for * 's1' elements referenced by 'array1' and 's2' elements by 'array2'. * The arrays' elements are set to 0. * * Returns a pointer to the freshly allocated memory or NULL if the memory could not * be allocated. */ Foo_t * Foo_CreateAndInit(size_t s1, size_t s2) { /* At once allocate all 'Foo_t' (including the memory Foo_t array pointers shall point to). */ Foo_t * pfoo = calloc(1, sizeof(*pfoo) + s1 * sizeof(*(pfoo->array1) + s2 * sizeof(*(pfoo->array2))); if (pfoo) { pfoo->lengthOfArray1 = s1; pfoo->lengthOfArray2 = s2; /* The first array starts right after foo. */ pfoo->array1 = (Foo_ArrayElement1_t *) (pfoo + 1); /* The second array starts right after s1 elements of where the first array starts. */ pfoo->array2 = (Foo_ArrayElement2_t *) (pfoo->array1 + s1); /* That casting here is not necessaryas long as 'Foo_t.array1' and 'Foo_t.array2' point to the same type but makes the code work even if those types were changed to be different. */ } return pfoo; } ... Foo_t * foo = Foo_CreateAndInit(5, 5); 
+3
source

You must select the size of the structure. Then you need to select an array of values ​​with the appropriate sizes.

 foo* bar = malloc(sizeof(foo)); /* somewhere in here the array lengths are set then... */ bar->array1 = malloc(sizeof(int) * bar->lengthOfArray1); bar->array2 = malloc(sizeof(int) * bar->lengthOfArray2); 
+4
source

With a little extra memory (C99 only):

 #include <stdio.h> #include <stdlib.h> typedef struct foo { int lengthOfArray1; int lengthOfArray2; int *array1; int *array2; int array[]; } foo; int main(void) { foo *bar = malloc(sizeof(foo) + (sizeof(int) * 10)); bar->array1 = &bar->array[0]; bar->array2 = &bar->array[5]; /* 5 or lengthOfArray1 */ return 0; } 
+1
source

Source: https://habr.com/ru/post/1439607/


All Articles