2

I have the following code:

#include <stdio.h>

typedef struct {
  int* arg1;
  int  arg2;
} data;

int main(int argc, char** argv) {
  data d;
  printf("arg1: %p | arg2: %d\n", d.arg1, d.arg2);
}

The output ends up being that d.arg1 is not NULL and d.arg2 is 0. For example:

arg1: 0x7fff84b3d660 | arg2: 0

When I add a pointer to main, nothing changes. However, when I print that pointer:

#include <stdio.h>

typedef struct {
  int* arg1;
  int  arg2;
} data;

int main(int argc, char** argv) {
  data d;
  int* test;
  printf("arg1: %p | arg2: %d | test: %p\n", d.arg1, d.arg2, test);
}

the output always results in:

arg1: (nil) | arg2: 4195264 | test: (nil)

Why am I experiencing this behaviour? I don't understand how printing another pointer value changes the value of a different pointer to NULL. Note that the compiler I am using is GCC 4.8.2.

Alex Brooks
  • 1,151
  • 1
  • 10
  • 39
  • So the problem is just that my program experiences undefined behaviour? Not necessarily the coincidence that adding a new variable changes things? – Alex Brooks Jun 17 '14 at 21:40
  • This is typical, no surprise: if you use uninitialized values, and you add another variable, that can change what values you see in the original, uninitialized values. – pts Jun 17 '14 at 21:42
  • I don't think the difference is with you `printf`ing another pointer value, it is probably with you *allocating* another pointer on the stack. – Joel Cornett Jun 17 '14 at 21:48
  • init, *init*, **init**! – ikh Jun 17 '14 at 22:44

4 Answers4

5

You are experiencing this behavior because your program invokes undefined behavior. d is uinitialized in your program and hence its value is indeterminate and this invokes undefined behavior.

C11 6.7.9 Initialization:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

Quoting from this answer:

An indeterminate value even more unspecified than unspecified. It's either an unspecified value or a trap representation. A trap representation is standards-speak for some magic value which, if you try to assign it to anything, results in undefined behavior. This wouldn't have to be an actual value; probably the best way to think about it is "if C had exceptions, a trap representation would be an exception". For example, if you declare int i; in a block, without an initialization, the initial value of the variable i is indeterminate, meaning that if you try to assign this to something else before initializing it, the behavior is undefined, and the compiler is entitled to try the said demons-out-of-nose trick. Of course, in most cases, the compiler will do something less dramatic/fun, like initialize it to 0 or some other random valid value, but no matter what it does, you're not entitled to object.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
2

You should initialize d to get deterministic results:

data d = {0, 42};

or:

data d;
d.arg1 = 0;
d.arg2 = 42;

Without initialization, using the values leads to undefined behavior.

pts
  • 80,836
  • 20
  • 110
  • 183
2

You are accessing uninitialized values. This causes undefined behaviour (meaning that anything can happen, including the program crashing).

To fix, initialize values before using them, e.g.:

 data d = { 0 };
M.M
  • 138,810
  • 21
  • 208
  • 365
1

d is uninitialized, so it can contain anything.

Quentin
  • 62,093
  • 7
  • 131
  • 191