Hi! This was a question in our old C++ exam. This code is driving me crazy, could anyone explain what it does and - especially - why?
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
Hi! This was a question in our old C++ exam. This code is driving me crazy, could anyone explain what it does and - especially - why?
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
(*(arr+1)+=3)+=5;
arr + 1 - element with index 1
*(arr + 1) - value of this element
(arr + 1) += 3 - increase by 3
((arr+1)+=3)+=5 - increase by 5;
so arr[1] == 28
(arrp=&arr[0])++;
arr[0] - value of element 0
&arr[0] - address of element 0
arrp=&arr[0] - setting arrp to point to elem 0
(arrp=&arr[0])++ - set arr to point to elem 1
result: 28
This line:
(*(arr+1)+=3)+=5;
produces the same result as this (see footnote):
arr[1] += 3;
arr[1] += 5;
This line:
(arrp=&arr[0])++;
produces the same result as this (see footnote):
int* arrp = arr+1;
So this line:
std::cout<<*arrp
prints out 28
.
But this code leaks memory because int *arrp = new int;
allocates a new int
on the heap which will be lost on assignment by (arrp=&arr[0])++;
Footnote: Of course I'm assuming an absence of weirdness.
Edit: Apparently some of the lines in fact lead to undefined behavior, due to C++ Standard 5/4. So this really is a crappy exam question.
int arr[3]={10,20,30}; // obvious?
int *arrp = new int; // allocated memory for an int
(*(arr+1)+=3)+=5; // (1)
(arrp=&arr[0])++; // (2)
std::cout<<*arrp; // (3)
(1)
*(arr+1)
is the same as arr[1]
, which means that *(arr+1)+=3
will increase arr[1]
by 3, so arr[1] == 23
now.
(*(arr+1)+=3)+=5
means arr[1]
is increased by another 5, so it will be 28
now.
(2)
arrp
will pont to the address of the first element of arr
(arr[0]
). The pointer arrp
will then be incremented, thus it will point to the second element after the entire statement is executed.
(3)
Prints what arrp
points to: the second element of arr
, meaning 28
.
Well, remember that arrays can be interpreted as pointers
int arr[3]={10,20,30};
int *arrp = new int;
creates an array arr
of three integers and an int pointer
that gets assigned with a freshly allocated value.
Since assignment operators return a reference to the value that has been assigned in order to allow multi-assignment,
(*(arr+1)+=3)+=5;
is equivalent to
*(arr+1)+=3;
*(arr+1)+=5;
*(arr + 1)
refers to the first element of the array arr
, therefore arr[1]
is effectively increased by eight.
(arrp=&arr[0])++;
assigns the address of the first array element to arrp
and afterward increments this pointer which now points to the second element (arr[1]
again).
By dereferencing it in std::cout<<*arrp
, you output arr[1]
which now holds the value 20 + 3 + 5 = 28
.
So the code prints 28
(and furthermore creates a memory-leak since the new int
initially assigned to arrp
never gets delete
d)
This statement writes to the object *(arr+1)
twice without an intervening sequence point so has undefined behavior.
(*(arr+1)+=3)+=5;
This statement writes to the object arrp
twice without an intervening sequence point so has undefined behavior.
(arrp=&arr[0])++;
The code could result in anything happening.
Reference: ISO/IEC 14882:2003 5 [expr]/4: "Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression."
I'll try to answer you by rewriting the code in a simpler way.
int arr[3]={10,20,30};
int *arrp = new int;
(*(arr+1)+=3)+=5;
(arrp=&arr[0])++;
std::cout<<*arrp;
=== equals ===
int arr[3]={10,20,30};//create array of 3 elements and assign them
int *arrp = new int;//create an integer pointer and allocate an int to it(useless)
//(*(arr+1)+=3)+=5;
arr[1] = arr[1] + 3;//arr[1] == arr+1 because it is incrementing the arr[0] pointer
arr[1] = arr[1] + 5;
//(arrp=&arr[0])++;
arrp = &arr[0];//point the integer pointer to the first element in arr[]
arrp++;//increment the array pointer, so this really is now pointing to arr[1]
std::cout<<*arrp;//just print out the value, which is arr[1]
I am assuming you understand pointers and basic c.