-8
#include <iostream>

using namespace std;


int main() {
    int *a;
    int *b;
    int c=12;
    a=&c;

    *b=*b;
    cout << *b << endl;
}

The above code works fine, but the following code returns a segmentation fault error

#include <iostream>

using namespace std;


int main() {
    int *a;
    int *b;
    int c=12;
    //a=&c;

    *b=*b;
    cout << *b << endl;
}

Why?

gcc (Ubuntu 8.2.0-7ubuntu1) 8.2.0

  • 2
    What 'works fine' means for you? – SergeyA Nov 02 '18 at 19:07
  • 5
    Because undefined behavior is undefined. – πάντα ῥεῖ Nov 02 '18 at 19:07
  • I'm surprised there isn't a canonical answer for why using an uninitialized pointer is bad. This problem gets posed a lot and it would be nice to reference a single, concise question as a duplicate. – alter_igel Nov 02 '18 at 19:11
  • @alterigel see [Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?](https://stackoverflow.com/q/23415661/1708801) which covers the general topics of using an unintialized value. – Shafik Yaghmour Nov 02 '18 at 19:12
  • 1
    `int *a;` means "`a` points to an `int`." Well, _which_ `int`??? – alter_igel Nov 02 '18 at 19:14
  • @ShafikYaghmour that might strictly speaking address why it's bad, but that Q/A is full of standardese and will make zero sense to a beginner. I would like to see a canonical answer to "What happens when I dereference an uninitialized pointer?", for example. – alter_igel Nov 02 '18 at 19:17
  • I understood what you said, but didn't fail with a = &c line – Cihad GUNDOGDU Nov 02 '18 at 19:19
  • @CihadGUNDOGDU • `a = &c;` is good code, why would that fail? – Eljay Nov 02 '18 at 19:23
  • That would just be because of bad luck. The results of dereferencing an uninitialized pointer are undefined, so `*b=*b;` can do anything from look like it worked to fail catastrophically to ending all life on earth as we know it (though that last one is very unlikely). It can do different things for any number of reasons. You could run it a million times without crashing and then crash the program at the most inopportune time. Undefined behaviour is undefined. – user4581301 Nov 02 '18 at 19:24
  • @Eljay `a = &c;` would not, but I believe the Asker is troubled by why the `*b=*b;` that followed it did not cause a crash. – user4581301 Nov 02 '18 at 19:25

2 Answers2

4

Here's a step-by-step breakdown of what your code is doing:


int *a;
int *b;

This declares two pointers to int named a and b. It does not initialize them. That means that their values are unspecified, and you should expect them to be complete garbage. You can think of them as "wild" pointers at this moment, which is to say that they don't point to valid objects, and dereferencing them will cause Undefined Behavior and introduce a plethora of weird bugs, if not a simple crash.


int c=12;

This creates a simple local variable c of type int, which is initialized, with a value of 12. If you hadn't initialized it, as in int c; then it would also be full of garbage.


a=&c;

This snippet sets the pointer a to point to c, which is to say that the address of c is assigned to a. Now a is no longer uninitialized, and points to a well-defined location. After this, you can safely dereference a and be assured that there is a valid int at the other end.


*b=*b;

Here, you are dereferencing b, which means that you are reaching into your programs memory to grab whatever is pointed to by b. But b is uninitialized; it is garbage. What is it pointing to? Who knows? To read from the address it points to is like Russian roulette, you might kill your program immediately if you get really unlucky and the Operating System or runtime environment notices you doing something that's obviously wrong. But you also might get away with it, only for weird and unpredictable bugs to emerge later. This weirdness and unpredictability is why a good C++ programmer avoids Undefined Behavior at all costs, and ensures that variables are initialized before they are used, and makes sure that pointers are pointing to valid objects before dereferencing them.

Why does there appear to be a difference depending on a=&c;?

As to why your program apparently crashes or doesn't crash depending on how you initialize the other pointer, the answer is that it doesn't matter. In both cases, you're causing Undefined Behavior; you are breaking the language's rules and you should not expect the language to behave correctly for you thereafter, and all bets are off.

alter_igel
  • 6,899
  • 3
  • 21
  • 40
2

"*b=*b" - Is broken code. b is uninitialised, so you are dereferencing an uninitialised pointer. That's Undefined Behaviour. The program is broken and has no meaning according to the standard and the compiler is allowed to generate whatever code it feels like (no diagnostic required).

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70