【问题标题】:Difficulties to understand pointers, dynamic allocation and call to functions behaviour难以理解指针、动态分配和函数调用行为
【发布时间】:2018-06-29 16:31:37
【问题描述】:

我在 C 中工作。

我有一个名为 Entity 的简单结构

typedef struct Entity
{
    int x, y;
    int velX, velY;
}Entity;

我正在创建一个 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,而是一些随机数。我真的不明白为什么。

【问题讨论】:

  • 请注意,realloc() 函数会增长一个数组(因此您不必像在 addEntity() 中那样将旧的复制到新的副本中)。另请注意,当您不断移动数据时,一次增长一个元素会导致二次(缓慢)行为。分配一些空数组元素并使用额外的元素;当没有空闲时,将分配的数量加倍。其他策略是可能的,但一次一个是不好的。 (如果数组中只有两个实体,这当然无关紧要。但首先你不需要动态分配。)

标签: c arrays pointers struct dynamic-allocation


【解决方案1】:

原因是 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.
}

然后你调用另一个函数来改变它的值 - 没关系。但是,当您从函数返回时,该局部变量中的所有内容都消失了。

如果你这样做 - 那么它会起作用。

main()

addEntityAndSetValues(&entities);

addEntityAndSetValues()

void addEntityAndSetValues(Entity** entities)
{
    addEntity(entities, 1);
    changeValue(&(*entities)[0], 10);
    changeValue(&(*entities)[1], 20);
}

在这里它起作用了,因为您已经在 main() 中传递了变量的地址,然后您对该变量进行了更改 - 并且它的值的每一次更改都反映了。

【讨论】:

  • 我明白了,我尝试写addEntityAndSetValues(&amp;entities);并将原型替换为Entity** entities,然后我删除了函数中的每个&amp;,结果是10和一个随机值。
  • @Drakalex.: 检查一下,,,,
  • 哦,对,我不确定,但我想我明白它是如何工作的。我以前从未见过这种语法,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
相关资源
最近更新 更多