Ok so this one has me really confused. I'm working on a HW problem, and discovered something that was really weird to me. here is the function and call in question
int find_oldest_frame(int **a, int size)
{
int min = clock();
int **ptr;
int *ptr2;
int frame = 0;
int i;
// get address of pointer so we can modify it
ptr = a;
// store off original pointer location.
ptr2 = *a;
for (i=0; i<size; i++)
{
// Who is the oldest time
if (**ptr < min)
{
min = **ptr;
frame = i;
}
printf("Current_Pointer %d\n", *ptr);
*ptr++; // For some reason ++ doesn't work.
}
// now store the oldest frame with the current system time, so it's no longer the oldest.
*ptr = ptr2;
*ptr += frame;
**ptr = clock();
*ptr = ptr2;
// Return the array index so that we can change the right page!
return frame;
}
So to make a long story short, I get a popup (in windows) that says there was a problem and has to close.
When I try replacing *ptr++; with *ptr+=1;
The program runs. This got me interested so I used -S in gcc With the *ptr++ version I get this instruction:
addl $4, -20(%ebp)
with *p+=1 I get
movl -20(%ebp), %eax
movl (%eax), %eax
leal 4(%eax), %edx
movl -20(%ebp), %eax
movl %edx, (%eax)
Which to me looks like a very similar operation, so assuming I'm reading this correctly,
case 1
Increment -20(%ebp) by 4 (assuming $4 means that)
case 2
we store what is in ebp to eax,
(not sure what () do), but do it again?
then take and load the address from eax offset by 4 into edx,
now copy ebp back into eax again,
now copy edx into eax,
I mean it looks like they're doing the same thing, but for some reason *ptr++ != *ptr+=1
Why? What am I missing from what I see?
EDIT: THANKS Everyone now I feel special, I can't believe I didn't realize that!
This is actually an issue with the operator precedence. The postfix increment operator gets applied before the pointer is dereferenced, meaning that you increment the value of the pointer (the memory it points to) and then attempt to dereference it. This is invoking undefined behaviour since it points to a single int
.
In the latter case, the +=
is applied after the dereference occurs, so you get the value stored at the pointer's memory, then you add to it. You need to make sure the dereference occurs first if you want to use postfix increment, which you can do by using:
(*ptr)++;
instead of what you currently have.
This
*ptr++; // For some reason ++ doesn't work.
should be
(*ptr)++;
Operator precedence matters here - *ptr++
works this way: *(ptr++)
- the same way as
while( ( *t++ = *s++ ) != 0 );
copies a null-terminated string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With