Help with two pointer problems in C.

  • Thread starter Thread starter MorrowUoN
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around understanding two C programming problems involving pointer manipulation and array operations. Participants analyze the behavior of pointer increments and the effects on variable values and array elements after executing specific code sequences. The scope includes technical explanations and conceptual clarifications related to pointers and memory addresses.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested
  • Homework-related

Main Points Raised

  • Some participants propose that the value of y after the first code snippet is 0x1001 and x is 0x1000, attributing this to the post-increment behavior of the pointer y.
  • Others argue that the understanding of pointer arithmetic and the post-increment operator is not fully grasped, suggesting that y points to the address of x and increments after the assignment.
  • A participant expresses confusion regarding the second code snippet, questioning whether the array x is modified due to the lack of a unary operator.
  • Some participants clarify that pointer arithmetic is scaled by the type of object being pointed to, affecting how increments operate on pointers.
  • There is a discussion about the legality of accessing memory locations one past the end of an array, with some participants asserting that this is a valid operation in C.
  • Concerns are raised about potential segmentation faults when dereferencing pointers that point to invalid memory addresses, particularly in the context of single integer pointers versus array pointers.

Areas of Agreement / Disagreement

Participants express differing views on the interpretation of pointer behavior and the implications of pointer arithmetic. There is no consensus on the correct understanding of the code snippets, and multiple competing interpretations remain unresolved.

Contextual Notes

Participants highlight limitations in understanding the precedence of operators and the implications of pointer increments, which may lead to confusion about the resulting values of variables and the legality of certain operations in C.

MorrowUoN
Messages
8
Reaction score
0
What is the value of x after the following C code sequence?
Discuss the value of y.

int x = 0x1201, *y;
y = &x;
*y++ = 0x1000;

Analyse the following code and provide the values of the elements of the array x
after the code is executed.
int x[] = {1, 2, 3, 0, 5, 6, 0};
int *px = x;
do
{
*px += *x;
px++;
} while (*px != 0);

Any help is appreciated, thanks.
 
Physics news on Phys.org
These look like homework problems. We need to see your thoughts on what you think the code does before we can help.

For the first problem, you can see that y points to x so ask yourself what happens first the assignment of 0x1000 or the ++ increment of the y integer pointer?

For the second, look at the loop what is it doing? px --> x which means it points to x[0]
 
  • Like
Likes   Reactions: 1 person
For the first question I got:

y=0x1001 and x= 0x1000

My logic for this was y is pointing to the address of x and since y++ is post increment it sets x to 0x1000 and then y increments and becomes 0x1001.Also these questions are from a sample final exam for which we haven't been given the solutions.
 
Last edited:
MorrowUoN said:
I'm confused with the second one since there is no unary operator,causing me to think that array x isn't changed.
I'm not sure if this is the source of confusion, but *x is a pointer, not a unary multiply.
 
MorrowUoN said:
For the first question I got:

y=0x1001 and x= 0x1000

My logic for this was y is pointing to the address of x and since y++ is post increment it sets x to 0x1000 and then y increments and becomes 0x1001.
You got the right value for x, but that was bit lucky. Your logic is incorrect, and your value of y is incorrect.

You appear to have a basic misunderstanding of pointers and the post increment operator.

As a hint, which of the following two expressions is the same as *y++ : *(y++) or (*y)++ ? You may need to consult a C precedence table.

What does *(y++) = 0x1000 do, in detail? How about (*y)++ = 0x1000 ?
 
  • Like
Likes   Reactions: 1 person
D H said:
You got the right value for x, but that was bit lucky. Your logic is incorrect, and your value of y is incorrect.

You appear to have a basic misunderstanding of pointers and the post increment operator.

As a hint, which of the following two expressions is the same as *y++ : *(y++) or (*y)++ ? You may need to consult a C precedence table.

What does *(y++) = 0x1000 do, in detail? How about (*y)++ = 0x1000 ?

I believe this to be correct: *y++ = *(y++)

The precedence table I looked at had ++ above unary *.

I'm having trouble with this *(y++) = 0x1000 due to never seeing anything like it before.

This is what I think it does although I could be wrong.

it sets *y = 0x1000 therefore x=0x1000 and then increments y so y = 0x1201 + 1 = 0x1202 ?
 
MorrowUoN said:
I believe this to be correct: *y++ = *(y++)

The precedence table I looked at had ++ above unary *.
That is the correct interpretation of *y++. So far, so good. In fact, the alternate interpretation (*y)++ = 0x1000 isn't valid code.


I'm having trouble with this *(y++) = 0x1000 due to never seeing anything like it before.

This is what I think it does although I could be wrong.

it sets *y = 0x1000 therefore x=0x1000 and then increments y so y = 0x1201 + 1 = 0x1202 ?
There are two things wrong here. One is the "and then". It's better to look at the post-increment operator as a function that saves the variable value, increments, and returns the saved value. This suggests that y is incremented first rather than your "and then increments y".

An even better way to look at it is that order must not matter. Consider the statement *y++ = *y--; What does this do? The answer is whatever the compiler wants. It would be perfectly valid for the compiler to call the function erase_my_harddrive() in response to this statement.


The second thing that's wrong is your interpretation of what happens to y. y is a pointer. It does not contain 0x1201 initially. It points to a location in memory that contains that value.

What does incrementing a pointer do?
 
So basically after that line y just points to the next available memory location?
 
MorrowUoN said:
So basically after that line y just points to the next available memory location?
It doesn't matter if the location is available or not, it ends up pointing to the next memory location after x, which may or not be "available" (it's possible but unlikely that trying to access the next memory location after x would cause a segmentation fault).
 
  • #10
MorrowUoN said:
So basically after that line y just points to the next available memory location?

It depends on what you mean by the next "available" memory location. Pointer arithmetic, including increment and decrement is scaled by the type of object being pointed to.

What this means is that an expression such as p++ depends on how p was defined. If p is defined as a char *, then incrementing p will result in an address that is one byte higher in memory. If p is defined as an int *, them incrementing p will result in an address four bytes higher in memory.

It's the same with expressions such as p + 1, where again, p is defined as a pointer to some specific type. The value of p + 1 depends on how p was defined. To repeat what I said before, pointer arithmetic is scaled by the type of object being pointed to.
 
  • #11
MorrowUoN said:
So basically after that line y just points to the next available memory location?
It points to "one past the end of x", whatever that happens to be. While it is not legal to access the contents of a "one past the end an array" pointer, it is perfectly legal to set a pointer so that it points to one element past the end of an array. In other words, the statement *y++ = 0x1000; is perfectly legal. Dereferencing y after this statement (e.g., x = *y) is illegal. That belongs to that extremely nasty class of things called undefined behavior. The compiler is free to interpret the second statement of *y++ = 0x1000; x = *y; as a call to erase_my_harddrive().

rcgldr said:
It doesn't matter if the location is available or not, it ends up pointing to the next memory location after x, which may or not be "available" (it's possible but unlikely that trying to access the next memory location after x would cause a segmentation fault).
A segmentation fault in response to *y++ where y points to a valid memory location (e.g., &x) is not possible in a compliant implementation. The standard is very clear on this. Pointing one past the end of an array is a perfectly legal operation.

Aside: C++ depends on this being legal. "One past the end" is effectively what the end() function of a container points to.
 
  • #12
D H said:
A segmentation fault in response to *y++ where y points to a valid memory location (e.g., &x) is not possible in a compliant implementation. The standard is very clear on this. Pointing one past the end of an array is a perfectly legal operation.
I was referring to the case of y = &x; ... y++; x = *y;. In this case y is a pointer to a single integer, not an integer that is part of an array. Depending on memory protection capabilities of a system, it's possible that the memory addresses immediately after x are set to invalid.

A more likely way to produce a fault would be in an embedded environment where instead of x, y was set to be a pointer to a integer that is the last valid address in a range of valid addresses.
 

Similar threads

  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 17 ·
Replies
17
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 2 ·
Replies
2
Views
791
Replies
1
Views
3K
  • · Replies 23 ·
Replies
23
Views
9K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 18 ·
Replies
18
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K