0

so I understand that global variables are evil, and programmers should avoid them. However, I have been doing some studying regarding potential vulnerabilities behind it, so that is the reason why I'm using it at the moment.

I have this toy example:

#define MAX_LENGTH 8

int counter = MAX_LENGTH;
int *size;

int main(int argc, char **argv)
{
    int value = atoi(argv[1]);
    size = &value;

    int *test;
    *test = value;

    printf("Hello World %d %d\n", *size, *test);
}

So the core question is that why for a global variable pointer, do I have to get the address of a variable to store the value stored in that variable?

My understanding of storing a value to a pointer is how I used the int *test; variable. I simply dereference this variable *test = value to store the value. However, I am curious why for global variable pointer *size, I cannot simply do *size = value, but instead must do size = &value.

I tried searching this question through StackOverflow, but maybe I didn't phrase the question right or such, so I could not find the relevant link for it.

I would appreciate any kind of tips, thank you in advance,

Kind regards,

Edit: Thanks everyone for the responses!

Jay
  • 373
  • 1
  • 10
  • 2
    "_global variables are evil, and programmers should avoid them_" - beginners, not programmers in general. Experienced programmer should use globals whenever it makes sense – Jorengarenar Sep 16 '21 at 20:53
  • 1
    The first time you initialize `size` is when you say `size = &value;`. Before that, what exactly would you expect `*size` to be referring to? The same actually applies to `test`, you're invoking undefined behavior by attempting to read the value of an uninitialized variable. – Nathan Pierson Sep 16 '21 at 20:54
  • 3
    `I simply dereference this variable *test = value to store the value. However, I am curious why for global variable pointer *size, I cannot simply do *size = value, but instead must do size = &value.` No, you _can not_ just do `*test = value;`. You were just lucky it didn't crash. – tkausl Sep 16 '21 at 20:54
  • You don't store a value in a pointer, pointer... points to a value somewhere. Where? The pointer points there. – Kaihaku Sep 16 '21 at 20:56
  • What do you expect to happen here: `*test = value;`? – Ted Lyngmo Sep 16 '21 at 20:57
  • @tkausl is correct. There is no difference between the local and global scenarios. In both cases, you need to do `test = &value;` – BHass Sep 16 '21 at 20:58
  • 1
    The difference is that the `size` pointer, being global, will be initialized to NULL. So dereferencing it (before assigning a value to it) will result in a segfault (on most systems). On the other hand, the declaration `int *test` does not initialize `test` to NULL. So dereferencing it (before assigning a value to it) is undefined behavior. It's kind of like being spun around before trying to hit a piñata. When you swing, you might A) swing and miss, B) hit the piñata, or C) hit one of your friends. If your code appeared to work, it's because you were lucky, and didn't hit anything valuable. – user3386109 Sep 16 '21 at 21:54

2 Answers2

2

Think of a pointer as a place in memory meant to store an address so that int *test, a pointer to an int, stores an address containing an int. When you first declare it, int *test, test has garbage as its value since you didn't initialize it. You were lucky that the garbage happened to be the value of "some address". When you set the value of that "garbage address" to value, *test = value;, you stored value (the int) in the "garbage address". If the random value in test happened to be an invalid address, like 0, your program would've crashed.

You should always initialize your pointers with a valid address, in this case an int address, before you store a value into that address. You may initialize you pointer with three kinds of addresses: nullptr, an address of an already existing integer, or an address dynamically obtained through new, for instance:

int *p = nullptr;  // valid value for a pointer, but 
                   // don't use it since it isn't pointing to a valid address yet

int value = 0;  // an integer stored in an address in the stack
int *q = &value;  // initialized with the address of value; it is said to point to value

p = &value;  // p now also points to value

int *r = new int(0);  // initialized with a dynamic address from the heap returned by new
                      // new also initialized the integer in the address with the value of 0
...
delete r;  // don't forget to destroy and free the dynamic memory when you're done using it
           // or you'll have a memory leak...

EDIT: As @Ben Voight commented. There is a difference in initialization between global and local pointers. Global pointers with no explicit initialization are implicitly zero-initialized, i.e. nullptr. On the other hand, local pointers that are not explicitly initialized are not, and they contain an indeterminate value.

Luis Guzman
  • 996
  • 5
  • 8
  • "there is no difference between global or local pointers when it comes to their initialization and values." Yes, there is. A global with no initializer is zero-initialized and becomes a NULL pointer. A local with no initializer has an indeterminate value. The NULL pointer can be compared to other pointer values. The indeterminate value must not be inspected in any way; you have to overwrite it. – Ben Voigt Sep 16 '21 at 22:27
  • @BenVoigt, you're correct. I've edited my answer to correct the statement. Thanks for pointing it out. – Luis Guzman Sep 17 '21 at 03:42
1
    int *test;
    *test = value;

It is undefined behaviour. The pointer is not initialized and it is not referencing a valid int object. Your code "works" only by accident - you did not overwrite anything important or the wild (initialized pointers are called this way) was not referencing the protected memory area. Never use any not initialized pointers or automatic variables.

It is a very serious C programming error. It does not matter if the pointer is defined in the file (global) or local scope. They behave exactly the same.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • "It does not matter if the pointer is defined in the file (global) or local scope. They behave exactly the same." is false. At global scope, the pointer is initialized to null (and does not reference a valid object, but can legally be compared to other pointer values). At local scope, the pointer is uninitialized (and doesn't even have a value, you cannot legally compare its value to other pointers) – Ben Voigt Sep 16 '21 at 22:14
  • @BenVoigt it is in context of two lines of code in my answer. It does not matter if pointer is NULL or wild. Dereferencing is the same wrong. – 0___________ Sep 16 '21 at 23:33