难以理解指针、动态分配和函数调用行为
Difficulties to understand pointers, dynamic allocation and call to functions behaviour
我在 C 工作
我有一个名为 Entity 的简单结构
typedef struct Entity
{
int x, y;
int velX, velY;
}Entity;
我正在创建一个实体类型和大小为 1 的动态数组。然后我使用我的 addEntity
函数添加一个元素
void addEntity(Entity** array, int sizeOfArray)
{
Entity* temp = malloc((sizeOfArray + 1) * sizeof(Entity));
memmove(temp, *array, (sizeOfArray)*sizeof(Entity));
free (*array);
*array = temp;
}
然后我用另一个函数来改变两个元素的值:
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;
}
结果是 10 和 20,一切正常。现在,如果我改用这种语法
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);
}
我没有得到 10 和 20,而是一些随机数。我真的不明白为什么。
原因是 C 是按值传递的。
当您在第二种情况下传递指针时 - 它的副本被传递给函数。现在当你写 &entities
它是局部变量的地址。 main
中的变量没有看到任何变化——因为你没有改变它们。所以你得到的是垃圾值。
更清楚
void addEntityAndSetValues(Entity* entities)
{
addEntity(&entities, 1); <--- entities is a local variable.
}
现在您添加调用 addEntity
:
void addEntity(Entity** array, int sizeOfArray)
{
...
free (*array);
*array = temp; <--- assigning to the local variable the address of the allocated chunk.
}
然后你调用另一个函数来改变它的值 - 这些都可以。但是当你从函数中 return 时,那个局部变量中的所有内容都消失了。
如果你这样做 - 那么它就会起作用。
在main()
addEntityAndSetValues(&entities);
在addEntityAndSetValues()
void addEntityAndSetValues(Entity** entities)
{
addEntity(entities, 1);
changeValue(&(*entities)[0], 10);
changeValue(&(*entities)[1], 20);
}
在这里它起作用了,因为您已经在 main()
中传递了变量的地址,然后您对该变量进行了更改 - 并且它的值的每个更改都会反映出来。
我在 C 工作
我有一个名为 Entity 的简单结构
typedef struct Entity
{
int x, y;
int velX, velY;
}Entity;
我正在创建一个实体类型和大小为 1 的动态数组。然后我使用我的 addEntity
函数添加一个元素
void addEntity(Entity** array, int sizeOfArray)
{
Entity* temp = malloc((sizeOfArray + 1) * sizeof(Entity));
memmove(temp, *array, (sizeOfArray)*sizeof(Entity));
free (*array);
*array = temp;
}
然后我用另一个函数来改变两个元素的值:
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;
}
结果是 10 和 20,一切正常。现在,如果我改用这种语法
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);
}
我没有得到 10 和 20,而是一些随机数。我真的不明白为什么。
原因是 C 是按值传递的。
当您在第二种情况下传递指针时 - 它的副本被传递给函数。现在当你写 &entities
它是局部变量的地址。 main
中的变量没有看到任何变化——因为你没有改变它们。所以你得到的是垃圾值。
更清楚
void addEntityAndSetValues(Entity* entities)
{
addEntity(&entities, 1); <--- entities is a local variable.
}
现在您添加调用 addEntity
:
void addEntity(Entity** array, int sizeOfArray)
{
...
free (*array);
*array = temp; <--- assigning to the local variable the address of the allocated chunk.
}
然后你调用另一个函数来改变它的值 - 这些都可以。但是当你从函数中 return 时,那个局部变量中的所有内容都消失了。
如果你这样做 - 那么它就会起作用。
在main()
addEntityAndSetValues(&entities);
在addEntityAndSetValues()
void addEntityAndSetValues(Entity** entities)
{
addEntity(entities, 1);
changeValue(&(*entities)[0], 10);
changeValue(&(*entities)[1], 20);
}
在这里它起作用了,因为您已经在 main()
中传递了变量的地址,然后您对该变量进行了更改 - 并且它的值的每个更改都会反映出来。