【问题标题】:Array of struct pointers - overrides struct结构指针数组 - 覆盖结构
【发布时间】:2013-05-14 18:26:47
【问题描述】:

我正在学习 C,但遇到了结构问题。

假设我有以下结构:

typedef struct {
  int x;
} Structure;

int main (void) {
  Structure *structs[2];
  for(int i = 0; i < 2; i++) {
    Structure s = {i};
    structs[i] = &s;
  }
  for(int i = 0; i < 2; i++) {
    printf("%d\n", structs[i]->x);
  }

  return 1;
}

输出是:

1
1

我不明白为什么新结构会覆盖旧结构。

这可能是一个愚蠢的问题。但我不明白。

谢谢!

已解决:

typedef struct {
  int x;
} Structure;

int main (void) {
  Structure *structs[2];
  for(int i = 0; i < 2; i++) {
    Structure *s = (Structure *)malloc(sizeof(Structure));
    s->x = i;
    structs[i] = s;
  }
  for(int i = 0; i < 2; i++) {
    printf("%d\n", structs[i]->x);
    free(structs[i]);
  }

  return 1;
}

【问题讨论】:

    标签: c arrays pointers struct


    【解决方案1】:

    对象s 不会超出第一个for 循环的范围。存储它的地址是没有意义的,并且取消引用它是未定义的行为

    【讨论】:

    • 谢谢!我得到了它!我将代码更改为使用堆作为存储。
    【解决方案2】:

    代码具有未定义的行为。您持有本地自动变量的引用。

    for(int i = 0; i < 2; i++) {
        Structure s = {i};
        structs[i] = &s;
    
    } // life time of s ends here
    

    所有赌注都取消了,因为代码有 UB。所以,你得到什么输出并不重要。

    【讨论】:

    • 变量不是本地的——如果是static,这里就不会有UB。正确(完整)的术语是 “本地自动” 变量。
    • @H2CO3:其实是“具有块范围和自动存储时长的对象”。我不相信该标准为此使用术语“本地” - 或就此而言使用“变量”。
    • @KeithThompson 是的,而是“块范围”——但我也没有暗示“变量”是术语的一部分(这就是为什么它在引号和斜体之外)。
    • @H2CO3 感谢您纠正我使用正确的术语。
    • @Mahesh 感谢 Keith Thompson - 事实证明我也不完全正确 :)
    【解决方案3】:

    Structs s = {i}; 仅在您声明它的 for 循环内具有作用域。一旦你离开那个循环,它就不再存在,即使你仍然有一个指向它的指针。之后都是未定义的行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      相关资源
      最近更新 更多