Help with two pointer problems in C.

  • Thread starter MorrowUoN
  • Start date
In summary: So, in the expression *y++ = 0x1000, although we do not know the type of y, assuming that it is defined as a pointer to some type, then y++ means "increment y by the size of the type that y points to". Since y points to an int, then y++ will increment y by 4 bytes.
  • #1
MorrowUoN
9
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
  • #2
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 1 person
  • #3
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:
  • #4
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.
 
  • #5
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 1 person
  • #6
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 ?
 
  • #7
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?
 
  • #8
So basically after that line y just points to the next available memory location?
 
  • #9
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.
 

1. What are two pointer problems in C?

Two pointer problems in C refer to a programming technique that involves using two pointers to traverse an array or linked list. This approach is often used to solve problems that require manipulating data in a specific order.

2. How do I declare two pointers in C?

To declare two pointers in C, you can use the syntax: data_type *ptr1, *ptr2;. This creates two pointers, ptr1 and ptr2, both of which point to the same data type.

3. How do I use two pointers to solve a problem in C?

To solve a problem using two pointers in C, you first need to identify the problem's requirements and determine which data structures to use. Then, you can use two pointers to traverse the data structure and manipulate the data as needed to solve the problem.

4. What are some common mistakes when using two pointers in C?

Some common mistakes when using two pointers in C include not properly initializing the pointers, not updating the pointers after traversing the data structure, and not considering edge cases in the problem solution. It is important to thoroughly test your code and double-check your logic to avoid these mistakes.

5. Can I use two pointers in C to improve the efficiency of my code?

Yes, using two pointers in C can often improve the efficiency of your code. By using two pointers, you can avoid unnecessary iterations through a data structure and reduce the time and space complexity of your program. However, it is important to carefully analyze the problem and use the appropriate data structures to ensure your code is efficient.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
984
  • Engineering and Comp Sci Homework Help
Replies
23
Views
7K
  • Engineering and Comp Sci Homework Help
Replies
18
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
880
  • Engineering and Comp Sci Homework Help
Replies
1
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
15
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
8
Views
1K
Back
Top