Why does an unassigned int have a value? - c++

If i run the following code it shows a long number.
int i;
int *p;
p= &i;
cout<<*p;
Why does an unassigned int have a value? And what is that value?

The value of the pointer p is the address of the int i. You assigned it with the address-of & operator: p = &i. The int i itself is not initialized also called default initialized. When you dereference your pointer with *p you get the value of your uninitialized int i which could be anything.
The value of your int i is the uninitialized memory interpreted as int. Using uninitialized variables is undefined behaviour.
Also you would have the same behaviour without a pointer by simply doing:
int i;
cout << i;

Because this is what "undefined behavior" means in C++.
"Undefined behavior" means "anything is possible". This includes:
You getting some random value for the object. It can be always the same, or different every time you run the code.
The program crashes.
Your computer starts playing the latest Justin Bieber video, all by itself, with no way to stop it.
The universe, as you know it, comes to an end.
etc... That's what "undefined behavior" means.

Imagine you want to buy a land, where you intend to build a house. To buy a land, you contact the local land seller.
You need to tell him how much units of land you need. In return, he will tell you the location of the land.
Done - your land is ready for use. But did you notice something ? The land seller only told you the coordinates of the land. He didn't say anything about the land. On the land there could be already existing house. There could even be a Hotel, or an Airport. Who knows what is there? If you try to use land, without building your house first, you have no guarantee what will be there. It is your responsibility as a land owner, to build something on top of the land, and use it as appropriate.
C/C++ is the same as the above example. Asking for a int, is like asking for a land with size of 8 units. C/C++ will give you the land, telling you its coordinates. It won't tell you what the land contains. You're responsible for using the land to put a house on top of it. If you don't put a house, and try to enter "the house", you might end up in a Airport. Hope it's clearer now :).

Simply because the memory location where i is has some value (whatever value it is). As Sam pointed out, it is a good example of undefined (and unwanted) behavior.

Because variables can't be empty.
Every byte of computer memory always contains something.
Computer programs usually don't clean up memory when they done with it (for speed reasons), thus when you leave a variable uninitialized, it will have some random (more or less) value which was left in this place of memory by another program or by our own code.
Usually it is 0 or a value of some other variable that was recently destructed or some internal pointer.

The current contents of the memory location ( in the stack ) of the variable i.

Related

Using garbage value(not initialized value) as id

Before ask I'm not the native speaker pardon for my poor english
Reading some book about c++ and the book mentioned variables should be initialize after declared. Otherwise variable having a garbage value and this may cause some problem. This garbage values are random and not predictable, what if using this garbage value as a ID?
I tried to find relational topic an google and couldn't find any result
Please leave a comment of idea of references
When you initialize a non-static(local) variable and use/read/print it before assigning a variable to it, the action is undefined behavior.
When you encounter undefined behavior:
You cannot assume that there's any value in that memory space to begin with
You cannot assume that the value won't change throughout the code execution, therefore, it's not ideal to use it as an ID
You cannot even assume that the program will run, or it will crash/freeze/etc... as everything action from that point on is undefined
Theoretically, an undefined behavior permits anything to happen (obviously in reality there's many restrictions to try and keep it from doing everything and probably sending everyone your pictures, corrupt all your files and frying your computer afterward).
For example, with this piece of code:
int num;
int a = num;
int b = num;
When you print it out, a and b is not guaranteed to have identical value, or the program will run at all. It's different with each systems/compilers.
As such, one must never rely on an undefined behavior to act normally.
Quote from #AnT:
So in general, the popular answer that "it is initialized with
whatever garbage was in memory" is not even remotely correct.
Uninitialized variable's behavior is different from that of a variable
initialized with garbage.
However, never mistakes undefined for inconsistency/randomness. For a (pretty bad) real life example, a broken pipe may be unexpected behavior, but the stream of water that hits you isn't inconsistent or random (until the pipe is fixed, of course).
An example when undefined behavior isn't simply taking some garbage value and results in some bizarre stuff: https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633
Related :
Uninitialized variable behaviour in C++
What happens to a declared, uninitialized variable in C? Does it have a value?
Nothing guarantees that an uninitialized variable contains garbage. It may be garbage, but in fact, any access to such variable yields undefined behavior, which means that literally anything may happen. It may be garbage, it may be constant, it may crash, it may contain previously used data, it may work like expected, but only with some compilers, etc. One is not supposed to rely on anything that comes from such variable and build any logic based on that. And, certainly, it cannot be a source of uniqueness or randomness.
First of all you should not use garbage value as ID.
Since not detail about your question, I am Considering your id is an unique value also by using your ID you are going to retrieve some value.
if that is the case then,
you cannot because on each and every run your garbage value may change.
And Garbage value in the sense it may be a numerical alphanumerical even not a proper value may come.

why wild pointer holds zero address rather than garabge address?

I have been trying to find the size of an particular datatype like "int" without using sizeof() and found this :
#include<stdio.h>
int main() {
int *ptr; /*Declare a pointer*/
printf("Size of ptr = %d\n",ptr);
ptr++;
printf("Size of ptr = %d\n",ptr);
return 0;
}
This returns correct size for int. How?
Isn't wild pointer suppose to contain garbage address rather than zero. And if it contains zero how is it different than NULL pointer as NULL is (void*)0 ?
Since ptr is uninitialised, its value is indeterminate and accessing its value gives undefined behaviour. The meaning of "undefined", somewhat ironically, is defined by C and C++ standards to mean something like "this standard doesn't constrain what happens".
Beginners often incorrectly assume this means it must contain a "garbage value" or be a "wild pointer" or "add some colourful description here" but that is simply not the case.
The meaning of "value is indeterminate" or "the behaviour on accessing the value is undefined" is that any behaviour is permitted from code that accesses the value.
Accessing the value is necessary to print it, increment it, or (in case of a pointer) dereference it (access contents of the address identified by the pointer's value).
The behaviour of code that accesses the value is undefined. Giving a printed value of zero, 42, or a "garbage value" are all correct outcomes. Equally, however, the result could mean no output, or undesirable actions, such as reformatting a hard drive. The behaviour may even change over time if the code is executed repeatedly. Or it may be 100% repeatable (for a specific compiler, specific operating system, specific hardware, etc).
Practically, it is quite common for code with undefined behaviour to give no sign of malfunction during program testing, but to later cause some nasty and visible but unintended effect when the program is installed and executed on a customer's computer. That tends to result in grumpy customers, bug reports that the developers may be unable to replicate, and stress for developers in trying to fix the flaw.
Trying to explain why undefined behaviour results in some particular outcome (such as printing a value of zero) is therefore pointless.
the first print will have garbage or zero, depends on your compiler and previous value that was in the memory location.
If it was zero, then the second print will have the size of int, because incrementing a pointer increments with the size of the pointee.
for instance:
char *x = 0;
x++; //x=1
int *y = 0;
y++; //y=4
In your case, if you got a 0 on the first print, it was the same as if you initialized it to NULL, but you can't count it to always be zero.

I am not exactly sure of the behavior of this code. Can someone explain it to me?

I am working with C++ and trying to wrap my brain around pointers. I have done the simple...
int a = 5;
int* b = &a;
int c = *b;
and then cout all the results. But I have then gone on to change the variable a to a different number and see the results, but only a changes and not the variable c. That is what I am not understanding. Can someone please explain to me why?
int c = *b; creates c and sets its initial value to the value pointed to by b. It does not create an enduring relationship between c and b. When *b or a are later changed, it does not change the value stored in c.
c is not a pointer. It is an integer.
When you initialised it, you gave it the value *b, which at that time was 5.
But from then on it's its own thing and has no relationship to b or to a.
Welcome to the wonderful world of pointers (my condolences). Although confusing at first, a few rules apply to pointers that make them very flexible. Pointers are just that: pointers to a location in memory.
The first line of code does not (directly) involve pointers. You the told computer to make a box named a - this box will contain an integer number - and then store the value 5 inside the box. In the background, the computer has to remember the location of the box you just made. Otherwise you wouldn't be able to use the box or the value!
The next instruction is more interesting. You make another box called b. Instead of putting a value in box, you told computer to put a sign in it. The computer knows you want it to make a sign because of the asterisk between the keyword int and the letter b - in C++, the asterisk marks a pointer when used in a declaration statement (typically on the left hand side of the single-equals sign, or sometimes simply before the semicolon when there is no single-equals sign). Then, you told the computer to write the location of the box a (indicated by an ampersand, the address operator) on the sign and put the sign inside box b.
Note: b contains a very specific kind of sign that is not interchangeable with a sign that points to, say, a char.
And now the hard part, the final line of code. Here you told computer to make a second integer-number box, called c. Then you told computer to take a picture of the value inside the box sitting at the location on the sign that b contains. This is my metaphor for the dereference operation (indicated by an asterisk in a statement that will be evaluated, typically on the right-hand side of the single-equals sign, or perhaps in a loop conditional, etc.). The computer looks at the location and sees that the value sitting there right now is 5. So the last line of code is evaluated and reduced to int c = 5.
The box c is now separate from and independent of a. So when you change either, the other is not affected. b was simply used as a roundabout proxy for a. You could have accomplished the same result with int c = a.
But believe me, for more advanced and dynamic applications, the ability to refer to a memory location instead of a value is game-changing. In fact, pointers are at the root of why today we can use easier to grasp, higher-level languages like Python and Java.
Best of luck in life and learning.

Is there a difference in compiling/executing code in different Operational Systems?

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.
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:
read the unspecified pointer value, get a trap representation, die with a hardware trap
OR read the unspecified pointer value, interpret it as an address which is misaligned, die with a bus error
OR follow the unspecified pointer to an unmapped address, die with a segment violation
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.
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. :)

Query regarding copying expression value to pointer using memcpy

I am looking to set the result of an expression(which is an int) into an int pointer. If I do the following:
int* a = new int;
memcpy(a, (int*)(3+4), sizeof(int));
I'm having trouble wrapping my head around it's expected behavior. Wll it copy the value 7 into a as expected. Or will it cause some undefined behavior
Nope, this won’t copy the value 7 in there. Instead, you get undefined behavior.
Think of writing memcpy(dest, source, size) as saying “please go to the memory address specified by source and copy size bytes from it. If you write (int *)(3 + 4), you get a pointer whose numeric value is seven, meaning that it points to memory address 7. Just as you wouldn’t expect house 137 on a block to be inhabited by people named Mr. and Mrs. 137, you shouldn’t expect the contents of memory address 7 to be the numeric value 7.
In fact, memory address 7 is unlikely to even be storage you can read or write from. You essentially “made up” an address with the typecast, and there’s no reason to believe there’s anything meaningful there. Imagine writing down a fake mailing address on a letter and dropping it in the mail. The odds that it actually reaches anyone is slim, and if it does reach them they’ll have no idea why you’re contacting them.
From a language perspective, this is undefined behavior, and on most systems it’ll segfault.