Im working on a auto tweet generation project for school.
I have the 2 structs
How the structs look [1]: https://i.sstatic.net/LGNQg.png
The dynamic array should be initialized with size of 1 WordProb object. For each new WordProb object i must realloc() the dynamic array by size of 1 WordProb and insert it.
I tried to use
WordStruct * ws1 = (WordStruct *)malloc(sizeof(*ws1) + sizeof(WrodProbability));
ws1->dynamic_arr_of_WordProb_objects[0].occurances = 4;
ws1 = (WordStruct *)realloc(ws1, 2 * sizeof(WrodProbability));
ws1->dynamic_arr_of_WordProb_objects[1].occurances = 4;
I have 3 questions:
Why don't i think my method is correct:
ws1->dynamic_arr_of_WordProb_objects[55].occurances = 44;
printf("Sizeof ws1: %d", sizeof(*ws1->next_words));
This printed 28.... How can this be sizeof(28) if it holds an array that holds other structures that are at least 24 byte big each? and how can i access index 55 if i never created it?
I'm very new to C, so every guidance will be helpful. Thanks!
After the G.O.A.T @jsiller answer, I think i might have got it. Is this the correct form to define a dynamic array in a struct, and realloc it later?
typedef struct{
int occurances;
}WrodProbability;
typedef struct {
WrodProbability next_words[];
}WordStruct;
int main()
{
WordStruct * ws1 = malloc(sizeof(*ws1) + sizeof(WrodProbability));
ws1->next_words[0].occurances = 1;
ws1 = realloc(ws1, sizeof(*ws1) + 2 * sizeof(WrodProbability))
}
Last question regarding the
ws1->next_words[55].occurances = 44;
issue. When i free(ws1->next_words) it will free all the memory from ws1->next_words[0] to [55]? Or only the first X amount of indexes i specified with realloc?
Thanks
Free(sw1) not working correct
WordStruct * ws1 = malloc(sizeof(*ws1) + sizeof(WrodProbability));
ws1->next_words[0].occurances = 1;
ws1 = realloc(ws1, sizeof(*ws1) + 2 * sizeof(WrodProbability));
ws1->next_words[1].occurances = 2;
printf("%d %p\n", ws1->next_words[0].occurances, ws1->next_words); // prints - 1 00000250023914a8
free(ws1);
printf("%d %p", ws1->next_words[0].occurances, ws1->next_words); // prints - 1 00000250023914a8
As you see there is still memory leak after i free(ws1). How can i free the Dynamic array correctly?
What you are using is (or used to be) called the struct hack.
I will use a different example to explain this:
struct foo {
int size;
int arr[];
}
The arr attribute of the struct is an array of size 0. The size of the struct now would be 4 because: (sizeof(size) = 4 + sizeof(arr) = 0) = 0.
To use arr you can now allocated the size of the foo struct plus the size of the err-type times the amount of elements you want to have. Lets convert this line of your code to the example:
WordStruct * ws1 = (WordStruct *)malloc(sizeof(*ws1) + sizeof(WrodProbability));
struct foo *f = (struct foo *)malloc(sizeof(*f) + sizeof(int));
which is equivalent to:
struct foo *f = malloc(sizeof(*f) + 1 * sizeof(int));
In this case we would have a struct foo allocated with an array of the size = 1. To allocate e.g. 50 elements you would adjust it to this:
struct foo *f = malloc(sizeof(*f) + 50 * sizeof(int));
Regarding you question to realloc, realloc takes the full size you want to size it to, not just the size you want to add. So if we want to add 25 more elements to the foo struct with 50 elements we would need to reallocate it like this:
f = realloc(f, sizeof(*f) + 75 * sizeof(int));
//75 because 50 + 25 = 75
to assign the first element in the array you can do it like this:
f->arr[0] = 1;
your code is correct but would assign the second element:
ws1->dynamic_arr_of_WordProb_objects[1].occurances = 4;
why can you access an element outside of the array? C does not protect you from accessing not allocated memory, it is undefined behavior and can cause your program to crash. That is why you should always store the size of your array and check it before trying to access your array.
Lastly why does this line print the "wrong" size
printf("Sizeof ws1: %d", sizeof(*ws1->next_words));
This is probably caused by your wrong usage of realloc, but I can not say this for sure, because you didn't share the code of your structs and in the images you shared I can not find any attribute called "next_words".