0

Wanting to truncate addresses for clarity. Not looking for improved code, just why the hex code subtraction does't seem to work properly.

First result with 'zero' being subtracted from 'cname' and 'arptr':

address of 'cname' is 0x7fff5fbff720
and of 'arptr' is     0x7fff5fbff720

Wanting to truncate unneeded digits for clarity I subtract 0x7fff5fbf0000 thinking I'll get 0x00000000f720, but:

Second result with 'trunker' being subtracted from 'cname' and 'arptr':

address of 'cname' is 0xffff00014082f720
and of 'arptr' is     0xffff00014082f720
#include <stdio.h>
#define trunker 0x7fff5fbf0000
#define zero    0x000000000000

int main(void) {

    char cname[3][3] = {'a','b','c','e','f','g','i','j','k'};
    char (* arptr)[3];

    arptr = cname;

    printf("address of cname is %p\nand of arptr is     %p\n",
    cname-zero,arptr-zero);   //replace zero with trunker 
                              //to truncate first 8 digits

    return 0;

}

Using Xcode on OS X

Thanks and Happy New Year 2012

Matt
  • 22,721
  • 17
  • 71
  • 112
Joel
  • 197
  • 1
  • 10

2 Answers2

4

Pointer arithmetic is performed in units of the thing being pointed to, not in units of bytes/chars.

You could try this instead:

printf("address of cname is %p\nand of arptr is     %p\n",
    (char*)cname-zero, (char*)arptr-zero);
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • That was it. Thanks for the lesson. output is now: address of cname is 0xf720 and of arptr is 0xf720 – Joel Jan 01 '12 at 17:04
2

According to the standard, thou shalt not use pointer arithmetic to compute addresses outside the original object (or at most one past the end). But if you convert to an integer first, you can do whatever you want (converting back to a pointer afterwards is legal, but inadvisable. According to the standard that is an unsafely-derived pointer.)

Better:

printf("address of cname is %zx\nand of arptr is     %zx\n",
       (intptr_t)cname-trunker,
       (intptr_t)arptr-trunker
      );

But if you just want to display the last four digits, this is even better:

printf("address of cname is %04x\nand of arptr is     %04x\n",
       (unsigned)cname & 0xffffU,
       (unsigned)arptr & 0xffffU
      );

Demonstration: http://ideone.com/t8gQn

Getting rid of warnings:

(unsigned)((intptr_t)someptr & 0xffffU)
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • That comes up with a compiler error, "Unknown conversion type parameter 0xa in format." That after including header – Joel Jan 01 '12 at 18:09
  • @Joel: Try the "even better" version. I'll look into it, but I think you just have a non-compliant static checker in your compiler. – Ben Voigt Jan 01 '12 at 18:11
  • @Joel: Found it, the `z` is a modifier, and need to be paired with a `%x` format specifier. And fixed. – Ben Voigt Jan 01 '12 at 18:14
  • The second gives me a compiler warning of "Cast from pointer to integer of different size." – Joel Jan 01 '12 at 18:14
  • @Joel: Yeah, that's exactly what you're trying to do, keep just part of the pointer. If you want that warning gone, I can add some more casts. – Ben Voigt Jan 01 '12 at 18:16
  • That's okay. I'm still trying to get me head around pointers of multiple arrays. A real mind twister. Thanks – Joel Jan 01 '12 at 18:18