Home > front end >  Different behaviour of struct in C'
Different behaviour of struct in C'

Time:10-02

I start learning C. It is fun. But I came to the point when I was trying to play around with struct. Below you have my program which I have created and I notice that behaviour of struct is different depend on how it was created.

When I run the program below my output is surprising. Output:

1. 1 0.000000 (some strange chars)
2. 0 0.000000 (null)

First of all like you can see the output of 1, 2 is different even if it is related to the same struct. Second of all number 3 is not printed at all.

I wonder why is that? I found on stackoverflow some explanation about the c struct but non of this post touch that issue. I was wonder if that is because of compiler? Or this is normal feature of C which I have to just understand? Or do I have even think about it?

#include <stdio.h>

struct s1 {
  int int1;
  double double1;
  char *string;
} strc;

typedef struct {
  int int1;
  double double1;
  char *string;
} DStruct;

int main() {
  struct s1 defqu;
  DStruct defqu2;

  printf("1. %d %f %s\n", defqu.int1, defqu.double1, defqu.string);
  printf("2. %d %f %s\n", strc.int1, strc.double1, strc.string);
  printf("3. %d %f %s\n", defqu2.int1, defqu2.double1, defqu2.string);
  
  return 0;
}

CodePudding user response:

You never initialized the instances you create, so it contains "garbage". Hence, you can expect "unexpected behavior" :)

Change it to:


struct s1 {
  int int1;
  double double1;
  char *string;
} strc = {0};

typedef struct {
  int int1;
  double double1;
  char *string;
} DStruct;

int main() {
  struct s1 defqu = {0};
  DStruct defqu2 = {0};

  ...

The syntax = { 0 } initializes all the values in the struct to 0. From the C99 Standard:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

This will be better, but still not perfect. The numbers will all be initialized to 0, and the string pointers (char * to be more accurate) will be initialized to NULL.

Modern libc implementation will handle the NULL pointer you pass to %s gracefully, but that's actually undefined behavior as well.

CodePudding user response:

strc is a global variable. It's guaranteed(by C standard) to be initialized to zero. So all the members of strc will also be initialized to zero (including the string pointer). When you try to print the string in the second printf (%s), you invoke undefined behavior (dereferencing a null pointer). Most likely the program crashes/terminates when dereferencing a NULL pointer, but that's not guaranteed by the standard. Because, you know, it's undefined behavior!

defqu and defqu2 are local variables inside main function. Local variables are never auto-initialized in C. So they have some garbage value and can't be guaranteed to be zero like in the case of strc. So the string pointer points to some random memory address and the first printf, most likely, printed the characters at that random memory location. You didn't see any output from the third printf because the program crashed/exited at the second printf because of the null dereference as explained above. Move this printf to the end, you'll see the output for defqu2 too, but you can never be sure(because, undefined behavior!)

  • Related