开发者

Help me understand this Strange C++ code

开发者 https://www.devze.com 2023-01-02 06:09 出处:网络
This was a question in our old C++ exam. This code is driving me crazy, could anyone explain what it does and - especially - why?

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=&a开发者_开发知识库mp;arr[0])++;

std::cout<<*arrp;


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."


(*(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 deleted)


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号