【问题标题】:Creating a struct on the stack within a function and assign it to an array's position of an array created in another function在函数内的堆栈上创建结构并将其分配给在另一个函数中创建的数组的数组位置
【发布时间】:2016-03-26 22:08:23
【问题描述】:

我需要在一个函数中初始化一个struct players 的可变长度缓冲区。到目前为止,这是我想出的:

#include<stdio.h>
#include<stdlib.h>

struct player{
    char name;
};

void players_init(struct player **players){
    *players = malloc(2 * sizeof(struct player));
    struct player p1, p2;
    p1.name = 'X';
    p2.name = 'Y';

    (*players)[0] = p1;
    (*players)[1] = p2;
}

int main(int argc, char *argv[])
{
    struct player *players = NULL;
    players_init(&players);
    printf("%c\n", players[0].name); // prints X
    printf("%c\n", players[1].name); // prints Y

    return 0;
}

我的问题是:因为我是在一个函数中创建 p1p2,所以这两个变量应该分配在专用于同一个函数的堆栈帧上,所以当该函数终止时,这些变量应该是走了。

从我的示例中可以看出,我将这些变量分配给缓冲区players 的位置,该缓冲区是在另一个函数中创建的。

我想知道为什么我的代码有效(如果它真的有效的话),因为我基本上是在引用变量,根据我的理解,当players_init 终止时应该不再存在。

我错过了什么?

【问题讨论】:

  • players_init 一次初始化一个玩家,并传递一个char 名称以供使用。然后将其命名为:players_init(&amp;players, 'X'); players_init(&amp;players, 'Y'); 这可能会如您所愿地破坏您的代码,因为您将覆盖未初始化的内存,让您现有的代码看起来正常工作。

标签: c arrays function struct


【解决方案1】:

因为您将整个结构复制到数组中,所以它可以工作。如果您只使用p1p2 的地址,那么您将有未定义的行为,因为正如您所说的p1 和p2` 超出范围。

您的情况是微不足道的,但在现实世界中,请注意您正在执行结构复制,因此您需要知道哪些位被复制,哪些不被复制

【讨论】:

  • 好的。所以,理论上我只需要在struct player 变量p 上创建并在分配之前更改其字段name,因为无论如何都会创建结构的副本......?
  • 是的。您可以用p 替换p1 和p2`,并使用相同的p 一个接一个地初始化数组中的项目。你是这个意思吗?
  • 是的。谢谢!你知道一个很好的教程来讨论与这个相关的问题,即我们什么时候应该小心等等?
  • 约翰指出,要非常非常小心,如果您的结构包含任何非静态成员,您的副本将失败,因为结构副本不是深层副本,所以如果相反,您的结构包含 @ 987654330@ 具有动态分配的名称,结构副本(赋值)不会复制 name 的内容,并且当堆栈帧在函数返回或退出时被销毁时,players_init 本地的任何数组或字符串都将丢失。
  • @DavidC.Rankin 好的,感谢您的建议,但我还没有完全理解。我的非静态成员你的意思是只动态分配内存的成员,对吧?如果不是,那还有哪些?例如,如果我在struct player 中有一个属于枚举类型的字段,那么这不会有问题,对吧?
猜你喜欢
  • 1970-01-01
  • 2012-12-03
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
相关资源
最近更新 更多