0

I have just found a problem and I have no idea what it could be. I started learning programming a few weeks ago and I am learning about pointers.

I compiled exactly the same code in 2 different PC's. In the first, the program runs perfectly. In the second, it stops working when it reaches a certain line.

I use 2 PC's. The one at my workplace runs Windows XP SP3. In this one, the program worked fine.

The one at my home runs Windows 7 SP1. It compiled the code, but the program did not work.

I am writing and compiling using DEV C++ and TDM GCC 5.1.0 in both systems.

#include<iostream>
using namespace std;

int main (void) {
  int* pointer;
  cout << "pointer == "  <<  pointer << "\n";
  cout << "*pointer == " << *pointer << "\n"; // this is the line where the program stops. 
  cout << "&pointer == " << &pointer << "\n";

return 0;}

The output in the first computer was something like:

pointer == 0x000001234
*pointer == some garbage value
&pointer == 0x000007865

In the second computer, it stops at second line.

pointer == 0x1

I do understand that the pointer have not been assigned to a variable. Therefore, it does not store any correct address. Even so, it should at least show the garbage value inside it, or a "0" to indicate it has not yet an address to point to. I know the code is right because it worked fine in the first PC. But I do not understand why it failed in other computer.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
user10906383
  • 323
  • 1
  • 8
  • Possible duplicate of [Confusion about the fact that uninitialized pointer points to anywhere](https://stackoverflow.com/questions/38863476/confusion-about-the-fact-that-uninitialized-pointer-points-to-anywhere) – Ken Y-N Feb 06 '19 at 00:15
  • 2
    Using a uninitialized variable results in Undefined behaviour. Since the behaviour is undefined, different systems may produce different behaviour. The same system could produce different behaviour only on Tuesdays. What you want to do is stick to defined behaviour. That way if different things happen on different systems someone else screwed up. – user4581301 Feb 06 '19 at 00:19
  • 2
    Dereferencing `*pointer` that has not been initialized is undefined behavior. If you are lucky, your program will crash. If you are unlucky, your program may appear to run correctly-ish. – Eljay Feb 06 '19 at 00:20
  • 1
    Answers don't go in comments and they don't go in the question. They go in the answer section. Seriously, this cannot be so difficult to grasp. – Lightness Races in Orbit Feb 06 '19 at 00:40
  • Fortunately, I do not care where I got my answers from. Thanks for your support. – user10906383 Feb 06 '19 at 00:51
  • @user10906383 But it matters to the site, in that there's a well-defined process for asking and answering questions--discussed in the FAQ. Denormalizing that process isn't helpful. – Dave Newton Feb 06 '19 at 01:09
  • @DaveNewton My issue was not about the rules, but the comentator's arrogance. I am a new user here and there is absolutely no reason to write in such tone. You in contrast correctly explained the rules in a fine and polite tone, TEACHING me something I did not know about this new environment. This is the very purpose of such sites: to facilitate us help each other. Mock/belittle/disregard new members who came here asking for help is just preposterous. I'm sick of this people. There's always some older haugty member. I thank you and I wish you best regards. – user10906383 Feb 06 '19 at 15:42

2 Answers2

3

I know the code is right because it worked fine in the first PC

You know no such thing.

You have undefined behaviour, and one entirely valid consequence is a program that always works. Or always works except on Saturdays, or always works until after you finished testing and shipped it to a paying customer, or always works on one machine and always fails on another.

The behaviour is undefined, not "defined to some specific consistent observable mode of failure".

Specifically, the real risk of undefined behaviour isn't simply that the result of some operation has an unspecified value, but that it may have undefined and unpredictable side-effects - on apparently-unrelated areas of your program, or on the system as a whole.

Even so, it should at least show the garbage value inside it

It did. But then you asked it to dereference that garbage value.

Reading any variable with an unspecified value is itself Undefined Behaviour, so the first piece of UB is reading the value of the pointer.

Following (dereferencing) a pointer which doesn't point to a valid object is also undefined behaviour, because you don't know whether the unspecified value you illegally interpreted as an address is correctly aligned for the type, or is mapped in your process' address space.

If you successfully load some integer from that address, that is a third piece of undefined behaviour, because again its value is unspecified.

So, the worst-case immediate pitfalls (with hardware trap values and restrictive alignment) are:

  1. read the unspecified pointer value, get a trap representation, die with a hardware trap
  2. OR read the unspecified pointer value, interpret it as an address which is misaligned, die with a bus error
  3. OR follow the unspecified pointer to an unmapped address, die with a segment violation
  4. OR survive all the previous steps - by pure chance - load some random value from some location in memory. Then die because that value is a trap representation.

But your if your process just dies, reproducibly, you can easily debug and fix it with no ill effects. In that sense, crashing at the point of invoking UB is actually the best possible outcome. The alternatives are worse, less predictable, and harder to debug.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • 1
    _"trying to read from an address that isn't mapped into your process' address space results in sudden death"_ Per your own description of UB in the previous section, sudden death is not guaranteed :P – Lightness Races in Orbit Feb 06 '19 at 00:45
  • It suddenly occurred to me that people's intuition about memory might be more like old single-user single-process machines than anything remotely modern. So, I thought I'd try to contrast them directly - but haven't really thought through how to combine the language and OS levels in a non-ridiculous answer... – Useless Feb 06 '19 at 00:50
  • Yeah it's pretty tough at this level of learning. FWIW I try to hammer home the abstract aspect, but I'm not convinced I've ever yet managed to do it in a way that triggers unlearning of the unwarranted low-level perspective! – Lightness Races in Orbit Feb 06 '19 at 00:57
2

I do understand that the pointer have not been assigned to a variable. Therefore, it does not store any correct address. Even so, it should at least show the garbage value inside it, or a "0" to indicate it has not yet an address to point to.

It did! That was the 0x000001234.

Unfortunately you then tried to dereference this invalid pointer, and print the value of an int that does not exist. You cannot do that.

If you hadn't done that, we'd have made it to the third line, where the 0x000007865 would correctly represent the address of the pointer, which is an object with name pointer and type int* that does indeed exist.

I know the code is right because it worked fine in the first PC.

One of the things you'll have to get used to with C++ is that "it appears to work on one computer" is very far from proof that the code is correct. Read about undefined behaviour and weep slow tears.

But I do not understand why it failed in other computer.

Because the code isn't right, and you didn't get "lucky" this time.

We could analyse a few reasons why it appeared to work on one system and not the other, and there are reasons for that. But it's late, and you're just starting out, and since this is undefined behaviour it doesn't matter. :)

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