0

I though I had finally understood pointers but then I encountered this issue:

typedef struct {
    unsigned int a;
    unsigned int b;
} Bar;

Bar *foo;

foo->a = 3;

This last instruction doesn't work (if I try to access foo->a somewhere else in the code, I either get 0 or rubish)... What am I missing?

Agnar
  • 117
  • 3
  • 3
    "doesn't work at all" how?, also you need to initialize the pointer to point to a proper Bar struct – ratchet freak Jul 03 '14 at 08:21
  • 2
    `Bar *foo;`, or as I prefer to set it out, `Bar* foo;`, is making a variable called foo of type *pointer to Bar*. It is not a Bar. There are no Bars in your program, so dereferencing `foo` will crash. If you're lucky. – Phoshi Jul 03 '14 at 08:30
  • Think of it this way: a pointer is just an address. To find a boyfriend or girlfriend, it isn't enough just to choose someone attractive and enter their phone number into your contacts list. You have to actually go out and meet them, charm them, and become partners! Compared to that, recording their number is the much simpler part. – Kilian Foth Jul 03 '14 at 10:24
  • C doesn't have a `this` pointer – Thomas Eding Jul 03 '14 at 18:21
  • @KilianFoth not really a good analogy; if you have someone's number then you do actually have a reference to someone; but in this case he's just typing random digits into his phone – M.M Jul 03 '14 at 22:28

1 Answers1

4

You need to actually create an object of type Bar and make the pointer foo point to it.

Bar *foo = malloc(sizeof *foo); // Create a new Bar on the heap
foo->a = 3;                     // Now it works

Or alternately, set the pointer to the address of another object:

Bar actualObject;               // Create a new Bar on the stack
Bar *foo = &actualObject;       // Set the pointer to the address of the actual object using '&'
foo->a = 3;                     // Now it works

//NOTE: actualObject.a will also be 3 because it is the same object internally.
metacubed
  • 7,031
  • 6
  • 36
  • 65
  • Can't do this in pure C, can I? oO –  Jul 03 '14 at 08:57
  • Thanks a lot, this a Phoshi's comment was what I needed :) –  Jul 03 '14 at 09:01
  • @Agnar Sure you can. I've added the pure C option to the first example. – metacubed Jul 03 '14 at 09:03
  • 1
    [Don't cast malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – M.M Jul 03 '14 at 22:28
  • @MattMcNabb You know, I had removed the cast and then added it back. Is skipping the cast portable to older compiler versions for both C and C++? I remember getting warnings on gcc telling me to add in that cast. – metacubed Jul 03 '14 at 22:36
  • The cast is needed in C++, it isn't needed in C... but the harm in link is a bit overwrought... you aren't going to mask an error with a cast from malloc, unless you are doing multiple levels of indirection. – Grady Player Jul 03 '14 at 22:44
  • Ah well, I just edited my example to follow those guidelines. – metacubed Jul 03 '14 at 22:53
  • @metacubed `void *` was officially added in 1989, although I believe common compilers supported it before that – M.M Jul 03 '14 at 22:54