why is this pass by pointer is not working as intended?

84 Views Asked by At

I am trying to understand why the following code does not work... please help:

void incme(double *p)
{
    printf("%x,%x\n",p,*p);
    *p = *p + 1;
    printf("%x,%x\n",p,*p);
}
int main()
{
    int i = 1;
    incme((double *)&i);    
    printf("%x,%x",&i,i);
}

the output is:

ff99a348,1
ff99a348,1
ff99a348,1

I am expecting: ff99a348,1 ff99a348,2 ff99a348,2
it breaks everything I know about pointers...

Thanks.

EDIT:

the main question i am asking the the type cast in incme((double *)&i); why isit not casting it to double and pass it to the function ? ... sorry for not pointing out eailer ....

3

There are 3 best solutions below

1
On

The main reason, the printf statements should read -

printf( "%p,%f", p, *p );

This will show your increment of the double.

Also - as stated, an int is generally 4 bytes and a double uses 8 bytes. (on most systems)

2
On

When you do *p = *p + 1; with p beeing a double* there is a lot going under the hood, indeed, double are represented using a custom format (wiki), when you use printf to display it as a integer after that, the internal representation of the memory at this address has changed (to a double representation), this is why you obtain such a result.

I ran the code and obtained the following output:

205afc2c,205afd28
205afc2c,593b4ab0
205afc2c,0

It shows use that the value is invalid as a double, and when it's incremented, it does not update the sizeof(int) first bits of the double (as it print 0 in the last line).

Hope I made myself clear !

Edit

I changed the code a little to show you what actually happen:

void incme(double *p)
{
    printf("%x,%lf\n",p,*p);
    *p = *p + 1;
    printf("%x,%lf\n",p,*p);
}
int main()
{
    int i = 1;
    incme((double *)&i);    
    printf("%x, %lf, %d",&i,i, i);
}

Gives me the following output:

cb90990c,0.000000
cb90990c,1.000000
cb90990c, 1.000000, 0

As you can see, if you print them as double, the value is indeed correct (but the binary representation of 1.0000 is not 00000000001 as I said previously, this is why the hex formatting gives you a large number). Back in the main, if you display the value as a double (event if i is supposed to be a int) as the incme function changed the memory layout of it, it does print 1.0000, but the first 32bits of the memory at this address are 0 hence, printing it as an int gives you 0.

3
On

Because of undefined behavior. Integers are not floating point, and floating point is not integers. Besides that, I think you will find that sizeof(int) != sizeof(double).

You're also breaking the strict aliasing rule.


Unrelated to your question, you should use the "%p" format if you want to print pointers.