0

I'm testing this piece of code, and the result is that the program crashes when reaches the << op in the first cout (because it prints out op = and then stops).

char *lo = 0, *op = 0, *ro = 0;
cout << "op = " << op << endl;
cout << "*op = " << *op << endl;

Now my question is: why this happens?

I know, pointer causes me a lot of problems..

Overflowh
  • 1,103
  • 6
  • 18
  • 40

5 Answers5

6

Because here:

cout << "*op = " << *op << endl;
//                  ^^^
//                  op is a NULL pointer!

you are dereferencing a pointer that does not point to any object, and that is undefined behavior.

So although the pointer is initialized, it is not initialized with the address of an existing object, and therefore you cannot dereference it meaningfully. Paragraph 5.3.1/1 of the C++11 Standard specifies:

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.

The Standard does not specify what the result should be when the expression is not pointing to any object: hence, it is undefined behavior.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • 1
    @Overflowh: It is initialized. But it is initialized with a value that doesn't point anywhere... Avoid the temptation to obsess over initialisation -- it's the pointer's resulting value that is important, whether that value came from random memory (as in the case of an uninitialized pointer) or from an initialization (as in this case) or even from an assignment. – Lightness Races in Orbit May 23 '13 at 12:35
  • @Overflowh: I expanded my answer a bit, but LightnessRacesInOrbit preceded my and gave you the right answer. The pointer is initialized, but it does not point to any object - therefore, dereferencing that pointer does not yield any defined behavior. – Andy Prowl May 23 '13 at 12:41
4

Short answer

Your question may be summarised thus:

I was taught that dereferencing uninitialized pointers is bad, and have come to the conclusion that this means all initialized pointers must be good. Am I right?

The answer is a resounding no.


Long answer

Uninitialized pointers aren't the problem.

The problem is with pointers that don't point to some decent storage in memory. This is usually the case for uninitialized pointers, but it's also the case when you deliberately assigned the pointer some useless value, like here.

For the purpose of pointing to a string, 0 is a useless value, because it indicates "this pointer does not point anywhere". Then attempting to dereference it is not okay.

It's not entirely clear what different behaviour you expected from this code.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

Going by your title "Pointer generate a crash also if it is initialized".

The pointer you created is not initialised to any memory location. When you initialise a pointer to 0 it means you are initialising it to NULL.

A pointer is supposed to hold a memory address (before you plan to use * on it) or NULL(to keep it from causing problems by modifying random memory location until you assign some memory location to it, before dereferencing. It also indicates that the pointer is currently inactive).

char *lo = 0, *op = 0, *ro = 0;

your pointers are currently NULL, not pointing to any memory location.

char a = 'A';
char * lo = &a; / char* lo = new char[10]; etc

Dereferencing a uninitialised or NULL pointer is undefined behaviour.

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
  • Initialising a pointer to be a null pointer is perfectly "correct". It is dereferencing this pointer later that is not correct. – Lightness Races in Orbit May 23 '13 at 14:33
  • @LightnessRacesinOrbit. Yes. What i wanted to indicate was it should point to a proper memory location. one which you have access to,and where you actually intend to modify (write, read) and it can be NULL but otherwise it can contain garbage pointing to some random memory location. I guess I will rephrase my sentences – Suvarna Pattayil May 23 '13 at 14:36
  • @LightnessRacesinOrbit Yes I guess what i wrote was really misleading. Thanks for pointing it out. Does my answer seem fine now? – Suvarna Pattayil May 23 '13 at 14:46
  • Yeah much better thanks (though the rationale for using NULL doesn't seem quite right). +1 – Lightness Races in Orbit May 23 '13 at 14:48
  • @LightnessRacesinOrbit Is it so? I always thought we need to initialise to NULL so that I don't accidently modify some location(without being aware what it is pointing to). – Suvarna Pattayil May 23 '13 at 14:52
  • 1
    Well, yes and no. It's true that a null pointer -- on _most_ systems -- will give you a nice and noisy segmentation fault if you attempt to dereference it; conversely, if you accidentally have a pointer with the wrong value in it, and you try to dereference that, you could very likely get silent and serious bugs. But the primary reason to set a pointer to NULL is to indicate to other pieces of code that it's "inactive" or "not in use" or "not pointing anywhere" -- there is no other value that can reliably be used to say that. – Lightness Races in Orbit May 23 '13 at 15:01
1

Your programme already crashes on the

cout << "op = " << op << endl;

line because there is an overload of the << operator for char* that interprets them as a pointer to the initial element of a 0-terminated character array and prints the characters before the next 0-byte out, thus needing to dereference the pointer. But you initialised op to be a null pointer, hence dereferencing it invokes undefined behaviour, often resulting in a crash (segmentation fault).

Casting op to a different pointer type, e.g. a void*

cout << "op = " << static_cast<void*>(op) << endl;

would make that line work and print an implementation-defined representation of a null pointer.

You would then still have undefined behaviour (and most likely a crash) on the next line, where you explicitly dereference op.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
0

It's because you initialize the pointers to point to address zero, which is the same a NULL.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621