Reputation: 1483
I came across this code in an interview.
int main()
{
int **p;
p = (int **) new int(7);
cout<<*p;
return 0;
}
I was expecting some run time error at *p. But when I ran the code , it executed successfully with output "0x7". Can someone please explain me how is this working. Thanks.
Upvotes: 7
Views: 465
Reputation: 106196
int main()
{
int **p = (int **) new int(7);
cout << *p;
}
So, new int(7)
allocates sizeof(int)
bytes of memory and returns a pointer to it. Let's say that the memory happens to be at address X. Then X is cast to (int**)
and stored in p
.
*p
dereferences the int**
, which means it intreprets the int
value 7 at address X
as an int*
.
If sizeof(int*)
is larger than sizeof(int)
, then reading as an int*
will read beyond the buffer allocated with new
- always undefined behaviour regardless of the data types and any reintrepretation.
If it is the same size, the CPU will attempt to read the memory containing the integer 7 as an int*
- this will typically yield the value int*(7)
, but looking at the Standard 5.2.10.5:
A value of integral type or enumeration type can be explicitly converted to a pointer.* [Footnote: Converting an integral constant expression (expr.const) with value zero always yields a null pointer (conv.ptr), but converting other expressions that happen to have value zero need not yield a null pointer. --- end foonote] A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined.
So, the integer value is guaranteed to convert to some pointer value - nothing undefined - but the value is implementation defined. Still, being a reversible operation it's overwhelmingly likely that the int
7 will yield an int*
with value 7 - that explains the observed behaviour of outputting "7".
int
size, it will read a slice of the int
value and interpret that as a pointer. Depending on endianness that slice may be 0 or 7 or even something else, but again as an int
it must be convertible to some pointer value that will be displayed.Upvotes: 0
Reputation: 208406
The proper answer would be None of the above unless you are given some extra constraints. Basically the code is allocating an int
and interpreting that memory as if it was an int*
(through a reinterpret_cast
). The first problem is that, being a reinterpret_cast
, the result is unspecified in the general case, and if the size of int
is smaller than the size of int*
(think a 64bit architecture) the result is undefined behavior as you are reading beyond the size allocated in the new
call.
Upvotes: 5
Reputation: 9579
int main()
{
int **p; // declare pointer to pointer called p
p = (int **) new int(7); // new allocates integer initialized to value of 7 and returns a pointer. Cast the pointer to a point to pointer. p now represents a pointer to a pointer with contents of 0x7. If you called **p you would get the contents at address 0x7.
cout << *p; // dereference p, this yields a pointer, which is an int of value 0x7.
}
The question was most likely meant to test your knowledge of pointers, but doesn't seem very practical.
Upvotes: 0
Reputation: 258618
new int(7);
allocates memory for an int
whose value is 7
and returns a pointer to it.
int **p = (int **) new int(7);
tells the compiler to interpret that memory as an int**
.
cout << *p;
tells the compiler that at the address *p
is an int *
and to output its value. The value is 0x07
. (it treats the int 7
as an address). An extra dereference would result in a crash (well, undefined behavior to be precise).
Upvotes: 0
Reputation: 662
You create a new int and initialize it with value 7.
int *x = new int(7);
You than cast it to a pointer (eg memory address 7 or 0x07)
int **p = (int**) new int(7);
Then you show this address with cout.
*p is equal to (int*)7
It's a pointer with value 7.
Upvotes: 4