I'm working in C.
I have a simple struct named Entity
typedef struct Entity
{
int x, y;
int velX, velY;
}Entity;
I'm creating a dynamic array of type Entity and size 1. Then I add one element with my addEntity
function
void addEntity(Entity** array, int sizeOfArray)
{
Entity* temp = malloc((sizeOfArray + 1) * sizeof(Entity));
memmove(temp, *array, (sizeOfArray)*sizeof(Entity));
free (*array);
*array = temp;
}
Then I use another function to change the values of the two elements :
int main()
{
Entity* entities = malloc(sizeof(Entity)); // dynamic array of size 1
addEntity(&entities, 1); // add one element
changeValue(&entities[0], 10); // change the values of the first two elemebts
changeValue(&entities[1], 20);
printf("%d\n", entities[0].x); // print the values
printf("%d", entities[1].x);
free(entities); // free the memory
return 0;
}
void changeValue(Entity* entity, int nb)
{
entity->x = nb;
}
The result of this is 10 and 20, everything works fine. Now if I use this syntax instead
int main()
{
Entity* entities = malloc(sizeof(Entity)); // dynamic array of size 1
addEntityAndSetValues(entities);
printf("%d\n", entities[0].x); // print the values
printf("%d", entities[1].x);
free(entities); // free the memory
return 0;
}
void addEntityAndSetValues(Entity* entities)
{
addEntity(&entities, 1);
changeValue(&entities[0], 10);
changeValue(&entities[1], 20);
}
I don't get 10 and 20 but some random numbers. I really don't understand why.
Reason is C is pass by value.
When in the second case you pass the pointer - a copy of it is passed to the function. Now when you write &entities
it is the address of the local variable. And the variables in main
don't see any change - because you didn't change them. So you get garbage value.
To be more clear
void addEntityAndSetValues(Entity* entities)
{
addEntity(&entities, 1); <--- entities is a local variable.
}
Now you add call addEntity
:
void addEntity(Entity** array, int sizeOfArray)
{
...
free (*array);
*array = temp; <--- assigning to the local variable the address of the allocated chunk.
}
Then you call the other function to change it's value - those are alright. But when you return from the function then everything in that local variable is gone.
If you do this - then it would work.
In main()
addEntityAndSetValues(&entities);
In addEntityAndSetValues()
void addEntityAndSetValues(Entity** entities)
{
addEntity(entities, 1);
changeValue(&(*entities)[0], 10);
changeValue(&(*entities)[1], 20);
}
Here it worked because you have passed the the address of the variable in main()
and then you made changes to that variable - and every change in the value of it reflected.