0

Here is a simplified version of two structs I have:

struct MyStruct1 {
    double d;
}

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

I can initialize the second struct as follows:

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

but actually I have to initialize it this way (its because this struct is again part of a bigger structure that shall be initialized at once):

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

Both ways compile without any warnings but the data in the second solution gets corrupted.

I think that the inner array is not static and thus the .a-pointer gets invalid immediately.

Is there another way to tell the compiler to keep the data of the array in the memory?

6
  • 1
    The data shouldn't get corrupted. In this case static refers to linkage, not to storage duration. Are you sure you're not simplifying something important away ? Commented Sep 18, 2013 at 8:30
  • 2
    Where is b being declared? Can you post a small program that exhibits the problem? Commented Sep 18, 2013 at 8:31
  • Are the declarations at file level, or function/block? Commented Sep 18, 2013 at 8:43
  • I am getting the same output for both the cases. Can you post some code where you think data is getting corrupted ? Commented Sep 18, 2013 at 8:47
  • Welcome to StackOverflow! I made some corrections to your question to clarify it. Of course, feel free to revert any changes if you think they are invalid. Commented Sep 18, 2013 at 9:18

1 Answer 1

1

C99 standard §6.5.2.5 p6 says that:

The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

In both cases the varables should be properly initialized and valid for usage in the scope they are declared.

If you, however, return the structure from the function by value, the pointer will become invalid.

Here is a sample code I used for testing. Valgrind shows no errors.

#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);

}
Sign up to request clarification or add additional context in comments.

1 Comment

"Enclosing block" would be the scope that includes the declaration -- and not the declaration itself (just because an initializer list uses curly braces does not make it an "enclosing block"). I.e., if you declare in a function outside a block the inner struct would be a local variable. But +1 for the citation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.