-1

I am trying to define a pointer to a struct as a global variable and access the value of its variables in different functions. But I realized that the values are cleared after the next function call. Am I doing something wrong?

struct St {
  double* varDouble;
};

struct St* StGlobal;

void Fun1(){

 double initDouble[2][1] = {{1},{2}};

 StGlobal = (struct St*)malloc(sizeof(struct St));
 StGlobal->varDouble = *initDouble;
};

void Func2(){
 for (i =0;i<2;i++){
    printf("%d\n", StGlobal->varDouble);
   } 
};

int main(){
Func1();
Func2();  // value of StGlobal->varDouble is no longer what was assigned to it in Func1
};
Shaga
  • 170
  • 8

1 Answers1

1
void Fun1(){

 double initDouble[2][1] = {{1},{2}};

 StGlobal = (struct St*)malloc(sizeof(struct St));
 // OK. StGlobal points to a memory that was returned by malloc.
 // The memory will be valid after the function returns.

 StGlobal->varDouble = *initDouble;
 // Not OK. initDouble is a local 2D array. *initDouble is a pointer 
 // that is valid as long as initDouble is in scope. When the function
 // returns the pointer is not valid.
};

And

void Func2(){
 for (i =0;i<2;i++){
    printf("%d\n", StGlobal->varDouble);
    // StGlobal->varDouble is dangling pointer.
    // Also, you are printing a pointer using %d. ???
    // If you try to access the pointer here, the program will exhibit
    // undefined behavior since it is a dangling pointer.
   } 
};

After you allocate memory for StGlobal, you'll have to:

  1. Allocate memory for StGlobal->varDouble also using malloc, or
  2. Assign it to some other pointer that will be valid after the function returns.

Also. Don't cast the return value of malloc in C. See Do I cast the result of malloc?.

Additional info

You can force MSVC to treat a file as a C program file by setting a compiler option. In VS2008, I can do that in the following dialog box.

enter image description here

There is probably a similar way to change the setting in MSVC 2010.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    @Olaf, I thought of that but did not follow through since I used the OP's code to point out the issues. – R Sahu Jan 05 '16 at 18:05
  • @Olaf and @R Sahu thank you very much for your answers! I am building my code as C, but I still get this error when I don't cast malloc: a value of type void cannot be assigned to an entity of type St*. – Shaga Jan 05 '16 at 19:20
  • @Shaga, what compiler and version are you using? – R Sahu Jan 05 '16 at 19:25
  • I am pretty new to C. how can I check the compiler version? I am using VS 2010 on a windows machine. – Shaga Jan 05 '16 at 21:21
  • The compiler is most likely compiling the file as a C++ file, not C file. You can force the compiler to treat it as a C file by changing a command line option. – R Sahu Jan 05 '16 at 21:29
  • I agree with R.Sahu. A C compiler **must not** complain when assigning a `void *` to any other pointer. Even VC does not, although this compiler is know not to be standard-compliant since at least 16 years. – too honest for this site Jan 06 '16 at 09:08
  • Well, I made sure that I am compiling as C by setting "Compile As" to "Compile as C Code (/TC)" in properties->C/C++->Advanced. And also renaming my files from .cpp to .c. I am not sure what else I should do to force the compiler to build as C. – Shaga Jan 06 '16 at 11:16
  • It should be enough to just save the source file with the `.c` extension. Then the module would be compiled using the C compiler. – Jeff Mercado Jan 06 '16 at 19:20