Search code examples
cpointersmemorystackunions

C : pointer and union and address


I want to print out some address on a value. The following is what I got and got to print out what I want.

// I need the first address to start with zero.

void printoutAddr(char* x, int n, int sign) {

printf("   Address           +x00         +x04\n");
intptr_t y = (intptr_t)x;

// to round it down every 16 byte
char *z = (char *)((y + 15)&~15);
// or char *z = (char *)(y&~15);

if (sign>0) {
    for (int i=0; i<n; i++) {
        printf("%p     %.08x     %.08x\n"
               , (char *)(z+16*i)
               , *(char *)(z+16*i)
               , *(char *)(z+4+16*i);
    }
} else {
    for (int i=n; i>0; i--) {
        printf("%p     %.08x     %.08x\n"
               , (char *)(z+16*i)
               , *(char *)(z+16*i)
               , *(char *)(z+4+16*i);
    }
}
}

And output is like the following:

dumper outputs... 
   Address           +x00         +x04
0x7fff5ad8c980     000000b8     000000ff
0x7fff5ad8c990     000000a8     000000ff
0x7fff5ad8c9a0     000000e1     000000ff
0x7fff5ad8c9b0     00000001     00000000
0x7fff5ad8c9c0     00000000     00000000

But this looks ugly and I need to do this using union. And I get stuck trying the following.

void printoutAddr(char* x, int n, int sign) {
  printf("   Address           +x00         +x04\n");
intptr_t y = (intptr_t)x;

char *z = (char *)((y + 15)&~15);

  union ptrs {
   char * ptr ;
   int num ;
  } xptr ;

  xptr.ptr = z;
  xptr.num = n;

  if (sign>0) {
    for (int i=0; i<n; i++) {
      printf("%p     %.08x     %.08x\n"
          , (char *)(xptr.ptr+16*i)
          , *(char *)(xptr.ptr+16*i)
          , *(char *)(xptr.ptr+4+16*i));
    }
  } else {
      for (int i=n; i>0; i--) {
        printf("%p     %.08x     %.08x\n"
            , (char *)(xptr.ptr+16*i)
            , *(char *)(xptr.ptr+16*i)
            , *(char *)(xptr.ptr+4+16*i));
      }
  }

}

I am getting the error of

on the line printf("%p %.08x %.08x\n"

of Thread 1: EXC_BAD_ACCESS

And don't know how to fix it...

Is there any other way to print out the same thing using unions like above?


Solution

  • A union can hold either member, but not both. Which one is up to you (usually tracked in a separate variable).

    Note that

    xptr.ptr = z;
    xptr.num = n;
    

    corrupts the value of ptr, so when you later refer to it, it holds the wrong data, which leads to your BAD ACCESS error.