Pointers are just variables (and how I figured this out)

After submitting a handful of coding style fixes to the OPW kernel mentors, it was time to try some real code. The driver file I’ve been working on has a function that’s over five hundred lines long, with a tangle of nested conditionals that cause some of the lines to be indented way too far. The logical thing to do was to extract some of the switch cases into their own functions.

To do it correctly, though, I needed to send a bunch of automatic variables along with the extracted lines as parameters. This included pointers. I assumed it would be easy; but my experience is mainly with pointers to structs, and when I looked at my parameter list, I was honest with myself about how fudged it looked. Plus, I didn’t have the benefit of being lazy and letting my tools do my thinking for me. I don’t own this device, so I have to fully understand every character of what goes into my patch. Without testing it.

As I walked through the extracted lines, I realized I was assuming that since pointer variables are pointers, their referencing is already taken care of, and they can be passed around with impunity. But, since that was an assumption, was it indeed correct? And even if it was, did it give me a crystal clear understanding of my pointer variables’ states? Having defined my zone of uncertainty, I could create a test program. So I ran this:


      1 #include 
      2 
      3 void foo(int *ptr)
      4 {
      5     printf("content of ptr %p\n", ptr);
      6     printf("address of ptr %p\n", &ptr);
      7     ptr = ptr + 4;
      8     printf("content of ptr %p\n", ptr);
      9     printf("address of ptr %p\n", &ptr);
     10     putchar('\n');
     11     
     12     }
     13 
     14 int main()
     15 {
     16     int a = 2;
     17     int *pa = &a;
     18     
     19     printf("content of pa %p\n", pa);
     20     printf("address of pa %p\n", &pa);
     21     putchar('\n');
     22     
     23     foo(pa);
     24     
     25     printf("content of pa %p\n", pa);
     26     printf("address of pa %p\n", &pa);
     27     
     28     return 0;
     29     }

…and got this output:


content of pa 0xbfe65f58
address of pa 0xbfe65f5c

content of ptr 0xbfe65f58
address of ptr 0xbfe65f40
content of ptr 0xbfe65f68
address of ptr 0xbfe65f40

content of pa 0xbfe65f58
address of pa 0xbfe65f5c

Not only was the pointer value unchanged by the function, which was scary proof that I was wrong, the pointer’s address was different inside the function. What? Was the pointer being passed by value like…a plain old automatic variable?

The always helpful folks at Stack Overflow confirmed my suspicions. That’s exactly what it is, and it should be handled like one.


      1 #include 
      2 
      3 void foo(int **ptr)
      4 {
      5     printf("content of ptr %p\n", *ptr);
      6     printf("address of ptr %p\n", ptr);
      7     *ptr = *ptr + 4;
      8     printf("content of ptr %p\n", *ptr);
      9     printf("address of ptr %p\n", ptr);
     10     putchar('\n');
     11     
     12     }
     13 
     14 int main()
     15 {
     16     int a = 2;
     17     int *pa = &a;
     18     
     19     printf("content of pa %p\n", pa);
     20     printf("address of pa %p\n", &pa);
     21     putchar('\n');
     22     
     23     foo(&pa);
     24     
     25     printf("content of pa %p\n", pa);
     26     printf("address of pa %p\n", &pa);
     27     
     28     return 0;
     29     }

content of pa 0xbfef91d8
address of pa 0xbfef91dc

content of ptr 0xbfef91d8
address of ptr 0xbfef91dc
content of ptr 0xbfef91e8
address of ptr 0xbfef91dc

content of pa 0xbfef91e8
address of pa 0xbfef91dc
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s