0

I do not understand C programming pointers very well and I've tried searching the internet looking for information about using simple pointers related to structures. I have this simple program :

#include <stdio.h>

typedef struct
{
      int ia;
      int ib;
} num;

int main()
{

     num *pn;

     //int a = 4;

     pn->ia = 5;
     printf("Hello, I made it this far!\n");
     pn->ib = 10;
     pn->ia = pn->ib;

     printf("num = %d\n", pn->ia);

     return 0;
}

This code doesn't work until I uncomment the unused integer 'int a = 4;'

It doesn't seem to matter if I use gcc 32bit or 64 bit on Windows 10.

I want to learn to do this the right way and I don't believe that an unused variable should make it work!

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • 10
    Your `pn` points nowhere. Trying to write it is invoking *undefined behavior*. – Eugene Sh. Jan 02 '20 at 22:18
  • With gcc, using `-Wall -pedantic` (or even just `-Wall`) will warn you about using uninitialized variables. – Amessihel Jan 02 '20 at 22:22
  • As stated, `pn` needs to point to a valid memory location. Try `num my_num; num *pn = &my_num;` – kaylum Jan 02 '20 at 22:22
  • You have to initialize pn to point to something before assigning anything to its contents. Imaging it as an envelope, which should contain an address to which you send something. You open the envelope and nothing is in it. What will you do? :) – Alex B Jan 02 '20 at 22:22
  • 3
    If you are using gcc, do yourself a favor and enable all warnings and errors using (`-Wall -Wextra -Werror`). This code [should not compile](https://godbolt.org/z/s7Ko_H) if your compiler is property configured. – vgru Jan 02 '20 at 22:26
  • A pointer is simply a normal variable that hold the address to something else as its value. Just as a declaration of `int a;` would leave the value of `a` *indeterminate* until it is either initialized as part of the declaration or a value assigned, declaring `num *pn;` leaves the value of (i.e. the address held by -- where the pointer "points") *indeterminate* as well. You either initialize the pointer to point to something, e.g. initialization `num instance; num *pn = &instance;` or assignment `pn = &instance;` or you dynamically allocate space `pn = malloc (n * sizeof *pn);` – David C. Rankin Jan 02 '20 at 22:35
  • See also: https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior – user3386109 Jan 02 '20 at 23:14
  • Check out a value then because it seems that this caused kinda memory leak out there – midugh Jan 02 '20 at 23:36

2 Answers2

6

your pn is not initialized. Your program invokes Undefined Behavior and is simply wrong

You need to initialize it static or dynamic way.

num nl;
num *np = &nl;

or

num *np = malloc(sizeof(*np));
0___________
  • 60,014
  • 4
  • 34
  • 74
  • 1
    @anastaciu by "dereferencing"ish the variable, it is the size of the structure. – Christian Gibbons Jan 02 '20 at 22:37
  • 1
    @anastaciu actually it is a bad way to use types instead of objects in the sizeofs – 0___________ Jan 02 '20 at 22:42
  • 1
    @anastaciu It is not highly irregular, you are just not familiar with the practice. It comes with its own benefit that if you ever change what type `np` is, your allocation function will still allocate the correct amount of space without having to manually change the alloc. – Christian Gibbons Jan 02 '20 at 22:43
  • 1
    @anastaciu it is not "irregular". sizeof is evaluated compile time - not runtime and it is not a function. Nothing is dereferenced.. You are 100% wrong in your opinion – 0___________ Jan 02 '20 at 22:43
  • `type *tp = malloc(sizeof *tp);` is a very common and useful idiom for correctly allocating an object and assigning a pointer to it. – Lee Daniel Crocker Jan 02 '20 at 22:43
  • Okay thanks. I'd still like to know why uncommenting that int a makes it work though. – robarteman Jan 02 '20 at 22:49
  • 2
    @robarteman it does not work. It is just random behaviour. There is no too much sense in explaining Undefined Behaviours. Just do it the correct way. Avoid UBs. – 0___________ Jan 02 '20 at 22:52
  • 4
    It doesn't "make it work". It just causes different undefined behavior that might resemble "working" more than some other undefined behavior. – Lee Daniel Crocker Jan 02 '20 at 22:52
  • 1
    @robarteman just because it works now doesn't mean it will next time, or with different compiler options, or with a different compiler, or on your buddy's machine. [Undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) means just that,, the behavior is undefined. This can include appearing to work, seg faulting .. anything (you _hope_ it seg faults so you can find it and fix it). – yano Jan 02 '20 at 22:58
  • Since some of the comments feel my "irregular" comment is exagerated, I retract it and accept the approach of the majority. – anastaciu Jan 02 '20 at 23:55
  • @anastaciu your first comment is also wrong. I already gave you the link to an example https://godbolt.org/z/qSJEDe – 0___________ Jan 03 '20 at 00:07
0

You do not allocate storage for pn to point to.

Make it an array like this and you should be able to use it in the same way:

num pn[1];
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76