A Weird Thing I’ve Never Seen Before

While browsing some sample code recently, I encountered the following C language expression:

x = &(*ptr);

Both variables x and ptr are pointers. So what the heck is going on?

Often I copy a sample program from the Internet to see what it does. Because I typically don’t like the way the coder presents things (often because not everyone really understands pointers), I work with the code, modify it, and eventually concoct my own version.

In this instance, I dutifully copied the code, which dealt with reading data from a PNG image file. From the sample line above, the ptr variable references an array of pointers. So it can be declared as:

**ptr

Or:

*ptr[]

I use the latter format in my code, though I may change it to the ** format after I fully grasp what’s going on. In this case, the variable x (in my example) is pulling an address from one of the pointers (memory locations) stored in the ptr array. But what the heck is &(*ptr)? It looks terribly confusing.

My assumption was that the & and * operators canceled each other out, but I wasn’t sure. Though I enjoy using pointers and try to fully understand them, this notation befuddled me. So, I wrote this code to help unravel the mystery:

#include <stdio.h>

int main()
{
    char z,*p;

    z = 'A';
    p = &z;

    printf("%p == %p\n",p,&z);
    printf("%c == %c\n",*p,z);
    printf("&(*p) = %p\n",&(*p));

    return(0);
}

It’s best to explain what’s going on by viewing the output:

0x7ffee6841a6b == 0x7ffee6841a6b
A == A
&(*p) = 0x7ffee6841a6b

The first line compares the values of pointer variable p, which is assigned to the address of variable z, with the address of variable z directly. The values should be equal, and they are.

The second line compares the contents of each variable, first z directly and then z as referenced by variable p. Both are identical.

Finally, I perform the weirdo &(*p) operation on variable p. The result is the address of variable z, which is the original contents of variable p.

Because of these results, I confirmed my hypothesis that the & and the * operators cancel each other out.

Back in my PNG-reading program I edited the original statement to remove the redundancies.

The only puzzle that remains is how someone would think to use &(*p) as an operation in the first place? It could have been the result of a search-and-replace in the code. It could have been bad documentation at some point. Or, most likely, it could be yet another C programmer who doesn’t fully understand pointers and who piled on the operators and was fortunate enough to get the result he needed.

Pointers are mysterious and troubling to many coders. Yet apparently, some are bold enough to try this or that and publish the success on the Internet without ever fully understanding what’s going on. I hope you reach the point in your C programming career where you don’t have to do that.

4 thoughts on “A Weird Thing I’ve Never Seen Before

  1. It might be interesting to look at the intermediate assembly language to see what the compiler does with x = &(*ptr);

    Also, perhaps see what Valgrind thinks of it?

  2. As an old Assembly coder, the language lacks a & operator, so the expression isn’t possible. In Assembly, you use square brackets to find the value at an address:

    [label]     ;value at label/variable/location
    [bx]        ;value referenced by address in register BX

    To get the direct address, you use the label or register. For an indirect address, you load it, then reference:

    ld bx,address
    mv a,[bx]

    Otherwise, such a construction just couldn’t exist in Assembly.

  3. 1. Glad that I’m not crazy. This is probably an example of someone writing a prototype of PNG image-reading code and programmers just blindly copying it. I recoded the entire thing to make it tighter.

    2. I don’t see the point of testing to see whether something is a legitimate pointer. Especially given that it’s used as a pointer everywhere else in the code. In my code, the thing is malloc’d for goodness sake!

    Thanks for looking this up, Chris.

Leave a Reply