0

I am a c++ learner. Others told me "uninitiatied pointer may point to anywhere". How to prove that by code.?I made a little test code but my uninitiatied pointer always point to 0. In which case it does not point to 0? Thanks

#include <iostream>
using namespace std;
int main() {
    int* p;
    printf("%d\n", p);
    char* p1;
    printf("%d\n", p1);
    return 0;
}
10100111001
  • 735
  • 15
  • 31
Constantine
  • 164
  • 9
  • 2
    It depends on your system and compiler, understand, that "anywhere" includes `null` too, so you already proved it. – sheikh_anton Nov 22 '16 at 07:52
  • 1
    Accessing the value of an uninitialized variable is undefined behavior. Here you are printing the value of `p`, which can do anything it wants at this point. – user975989 Nov 22 '16 at 07:53
  • I guess it should be rephrased as "uninitiatied pointer does not point anywhere" – macroland Nov 22 '16 at 07:56
  • [to print pointer use `%p`](http://stackoverflow.com/q/9053658/995714). [Using the wrong format specifier invokes undefined behavior](http://stackoverflow.com/q/16864552/995714). And why do you `#include ` but then use `printf`? Using a function without declaration is undefined behavior too – phuclv Nov 22 '16 at 07:56
  • [What Every C Programmer Should Know About Undefined Behavior](http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html) – phuclv Nov 22 '16 at 07:59
  • Your code has a bug -- you try to print the value of `p` before you assign it a value. Fix the bug and the mystery will go away. – David Schwartz Nov 22 '16 at 08:11
  • Old MSVC compilers (I think I've last tried it in like 2008) did zero-initialize all memory areas when compiling **Debug** code. I would really be suprised if it weren't still the case, so I guess, your first task is trying to compile your code in **Release** mode. _note:_ I have compiled C/C++ code under Linux systems, but in a preconfigured environment and I did much less experimenting, so I don't know if they have the same behaviour. – mg30rg Nov 22 '16 at 08:58
  • "How to prove that": quote the standard. – bolov Nov 22 '16 at 09:06

3 Answers3

4

Any uninitialized variable by definition has an indeterminate value until a value is supplied, and even accessing it is undefined. Because this is the grey-area of undefined behaviour, there's no way you can guarantee that an uninitialized pointer will be anything other than 0.

Anything you write to demonstrate this would be dictated by the compiler and system you are running on.

If you really want to, you can try writing a function that fills up a local array with garbage values, and create another function that defines an uninitialized pointer and prints it. Run the second function after the first in your main() and you might see it.

Edit: For you curiosity, I exhibited the behavior with VS2015 on my system with this code:

void f1()
{
  // junk
  char arr[24];
  for (char& c : arr) c = 1;
}

void f2()
{
  // uninitialized
  int* ptr[4];
  std::cout << (std::uintptr_t)ptr[1] << std::endl;
}

int main()
{
  f1();
  f2();
  return 0;
}

Which prints 16843009 (0x01010101). But again, this is all undefined behaviour.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
  • 1
    _Out of plain curiosity:_ Did you compile using **debug** or **release** settings? _(Old MSVS used to zero-initialize memory areas in **debug** builds, which caused heisenbugs in the old days.)_ – mg30rg Nov 22 '16 at 09:00
  • this was in release mode, in debug mode I get `3435973836`, which is `0xCCCCCCCC` – kmdreko Nov 22 '16 at 09:04
  • Nice! Looks like somewhere in the way Microsoft have introduced an "uninitialized pointer" constant. – mg30rg Nov 22 '16 at 09:23
1

Well, I think it is not worth to prove this question, because a good coding style should be used and this say's: Initialise all variables! One example: If you "free" a pointer, just give them a value like in this example:

char *p=NULL;          // yes, this is not needed but do it! later you may change your program an add code beneath this line...
p=(char *)malloc(512);
...
free(p);
p=NULL;

That is a safe and good style. Also if you use free(p) again by accident, it will not crash your program ! In this example - if you don't set NULL to p after doing a free(), your can use the pointer by mistake again and your program would try to address already freed memory - this will crash your program or (more bad) may end in strange results. So don't waste time on you question about a case where pointers do not point to NULL. Just set values to your variables (pointers) ! :-)

Cherubim
  • 5,287
  • 3
  • 20
  • 37
0x0C4
  • 205
  • 1
  • 11
0

It depends on the compiler. Your code executed on an old MSVC2008 displays in release mode (plain random):

1955116784
1955116784

and in debug mode (after croaking for using unitialized pointer usage):

-858993460
-858993460

because that implementation sets uninitialized pointers to 0xcccccccc in debug mode to detect their usage.

The standard says that using an uninitialized pointer leads to undefined behaviour. That means that from the standard anything can happen. But a particular implementation is free to do whatever it wants:

  • yours happen to set the pointers to 0 (but you should not rely on it unless it is documented in the implementation documentation)
  • MSVC in debug mode sets the pointer to 0xcccccccc in debug mode but AFAIK does not document it (*), so we still cannot rely on it

(*) at least I could not find any reference...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252