0

这是我拥有的两个结构的简化版本:

struct MyStruct1 {
    double d;
}

struct MyStruct2 {
    struct MyStruct1* a;
    int i;
}

我可以按如下方式初始化第二个结构:

void InitStruct(struct MyStruct2 pMyStruct2) {
    static struct MyStruct1 A[] = { {.d=12} , {.d=17} , {.d=1} };
    *pMyStruct2 = (struct MyStruct2) { .a = A, .i = 3 };
}

但实际上我必须以这种方式初始化它(因为这个结构又是一个更大的结构的一部分,应该立即初始化):

void InitStruct(struct MyStruct2 pMyStruct2) {
    *pMyStruct2 = (struct MyStruct2) { 
        .a = (struct MyStruct1[]) {
            {.d=12} , {.d=17} , {.d=1}},
        .i=3 };
}

两种方式都可以编译而没有任何警告,但第二种解决方案中的数据已损坏。

我认为内部数组不是静态的,因此.a-pointer 立即变得无效。

还有另一种方法可以告诉编译器将数组的数据保存在内存中吗?

4

1 回答 1

1

C99 标准§6.5.2.5 p6 说:

复合文字的值是由初始化列表初始化的未命名对象的值。如果复合文字出现在函数体之外,则该对象具有静态存储持续时间;否则,它具有与封闭块关联的自动存储持续时间。

在这两种情况下,变量都应该被正确初始化并且在它们声明的范围内使用是有效的。

但是,如果您按值从函数中返回结构,则指针将变为无效。

这是我用于测试的示例代码。Valgrind显示没有错误。

#include <stdio.h>

struct MyStruct1 {
  double d;
};

struct MyStruct2 {
  struct MyStruct1* a;
  int i;
};

struct MyStruct1 A[] = { {.d=12} , {.d=17} , {.d=1} };
struct MyStruct2 b1 = { .a = A, .i = 3 };

struct MyStruct2 b2 = { .a = (struct MyStruct1[]) {
                                {.d=12} , {.d=17} , {.d=1}
                            },
                        .i=3 };



int main( void ) {
  struct MyStruct1 B[] = { {.d=12} , {.d=17} , {.d=1} };
  struct MyStruct2 b3 = { .a = B, .i = 3 };

  struct MyStruct2 b4 = { .a = (struct MyStruct1[]) {
                                {.d=12} , {.d=17} , {.d=1}
                            },
                          .i=3 };

  printf("b1->a.d=%1.2f\n", b1.a->d);
  printf("b2->a.d=%1.2f\n", b2.a->d);

  printf("b3->a.d=%1.2f\n", b3.a->d);
  printf("b4->a.d=%1.2f\n", b4.a->d);

}
于 2013-09-18T09:11:53.997 回答