# Homework Help: Help with two pointer problems in C.

1. Jun 19, 2013

### MorrowUoN

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.

2. Jun 19, 2013

### Staff: Mentor

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]

3. Jun 19, 2013

### MorrowUoN

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: Jun 20, 2013
4. Jun 20, 2013

### rcgldr

I'm not sure if this is the source of confusion, but *x is a pointer, not a unary multiply.

5. Jun 20, 2013

### D H

Staff Emeritus
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 ?

6. Jun 20, 2013

### MorrowUoN

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 ?

7. Jun 20, 2013

### D H

Staff Emeritus
That is the correct interpretation of *y++. So far, so good. In fact, the alternate interpretation (*y)++ = 0x1000 isn't valid code.

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?

8. Jun 20, 2013

### MorrowUoN

So basically after that line y just points to the next available memory location?

9. Jun 20, 2013

### rcgldr

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. Jun 20, 2013

### Staff: Mentor

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. Jun 20, 2013

### D H

Staff Emeritus
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().

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. Jun 20, 2013

### rcgldr

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.