0

I'm trying to understand uninitialized pointers in functions as a local variable. here is my code:

#include <stdio.h>
#include <string.h>

void big_p() {
    char big[150];
    memset(big, 'B', 150);
    }

void ptr_init() {
    char *p;
    char x = 'X';
    printf("P value: %p\n", p);
}

int main()
{
    big_p();
    ptr_init();
}

I have some questions:

  1. the pointer p is pointing to a random memory address! why it contains 0x424242... (hex of 'B')?
  2. if I remove the line "char x = 'X'; " the pointer p does not contains hex of 'B', why?!

thank you.

FIFO
  • 41
  • 6
  • 1
    Local variables aren't initialized automatically, so it is expected for `p` to point to some random address. In your particular case, both `big` and `p` happen to be located on the stack, so `p` is just "reusing" the part of the stack where `big` used to be (and `x` might affect that in some unspecified/undefined way) – Felix G May 15 '20 at 08:31
  • 2
    Welcome to the world of undefined behavior. – kiran Biradar May 15 '20 at 08:32
  • 1
    Thou shalt not read out uninitialised variables (`p` here)! – alk May 15 '20 at 08:34
  • 1
    Please also note that the behavior you describe only happens when you compile without optimizations. If you compile with `-O3`, `x` is optimized out and both versions behave the same (but again different to both of the `-O0` versions). This is one of the reasons you have to avoid undefined behavior. If you're still curious though, the reason why `x` affects the outcome in your case is that it forces the compiler to put `p` on the stack, and without `x` it would just be kept in a register (and therefore have a different, but still random, value) – Felix G May 15 '20 at 08:43
  • The question “why?” presupposes that there is a reason for that behaviour - and worse, that that behaviour can somehow be “expected” and/or can be relied upon. None of that is the case . When uninitialised variables are created, the compiler and runtime environment can do whatever they like on the day. As @FelixG mentions, the same patch of memory is being reused. The machine could - just as validly - have chosen an entirely different area of memory untreated to the Bs you created earlier. Golden rule : never read uninitialised memory ! – racraman May 15 '20 at 08:46
  • Another important thing: just because the content of an uninitialized variable is "random" doesn't mean that it can be used as a source of randomness for an RNG! There was a case in OpenSSL on Debian where someone tried to do that, which led to a serious vulnerability (https://security-tracker.debian.org/tracker/CVE-2008-0166). – Felix G May 15 '20 at 08:53
  • 1
    @racraman: Your comment contradicts itself by suggesting there is not a reason for the behavior and then giving a reason (“the same patch of memory is being reused”). And that shows there are in fact reasons, so it is reasonable to inquire about them. Furthermore, it is useful: Understanding how programs misbehave may not enable us to rely on that for production code, but it does give us information useful for debugging. Understanding how various behaviors result from errors can help us trace from symptoms to causes. These questions can also help teach students how compilers work. – Eric Postpischil May 15 '20 at 09:40
  • @EricPostpischil glad to see that i'm not the only one who thinks that actually explaining undefined behavior is much better than just saying "if you do that, demons will come flying out of your nose!". – Felix G May 15 '20 at 09:45

0 Answers0