Q:

(char *) cast for skip using offsetto

I am studying about secure coding.
In the second code example of the following page, there is a recommendation to use (char *) for "skip" variable.
https://www.securecoding.cert.org/confluence/display/seccode/EXP08-C.+Ensure+pointer+arithmetic+is+used+correctly
I am not quite sure about the address calculation in this example. So I made following code.
#include <stddef.h>
#include <iostream>
using namespace std;

// https://www.securecoding.cert.org/confluence/display/seccode/EXP08-C.+Ensure+pointer+arithmetic+is+used+correctly

struct big {
    unsigned long long ul1_1; // 8
    unsigned long long ul1_2; // 8
    unsigned long long ul1_3; // 8
    int si_4; // 4
    int si_5; // 4
};

void getAdrs(void *p) {
    cout << p << endl;
}

int main() {
    size_t skip = offsetof(struct big, ul1_2);

    struct big *s = (struct big *)malloc(sizeof(struct big));

    cout << skip << endl; // 8

    getAdrs(s               ); // 0x9a38008 
    getAdrs(s + skip        ); // 0x9a38108 (+256)
    getAdrs((char *)s + skip); // 0x9a38010 (+2)

    unsigned long long val[4];
    getAdrs(&val[0]); // 0xbfacc0f0
    getAdrs(&val[1]); // 0xbfacc0f8 (+8)
    getAdrs(&val[2]); // 0xbfacc100 (+16)

    free(s);
    s = NULL;

    return 0;
}

http://ideone.com/b5kmS4
It seems to me that both of the followings return incorrect address.
1) getAdrs(s + skip); // original non-compliant code
2) getAdrs((char *)s + skip); // recommendation
In this case, I think ((head address of struct big) + 0x08) should be obtained because the ul1_2 is located at the 8th byte counting from the head of the struct big. Is it right?
However, the case 2 above seems to return (head address of struct big + 0x02).
Am I correct, or my understanding about the address is incorrect?

A:

You are absolutely right! And so is your code! The only thing wrong is... your hexadecimal math. :)
getAdrs(s               ); // 0x9a38008 
getAdrs(s + skip        ); // 0x9a38108 (+256)
getAdrs((char *)s + skip); // 0x9a38010 (+2)

>>> print 0x9a38010 - 0x9a38008
8

(Honestly, don't feel bad. I spent five minutes staring at it and the linked docs before I saw it. I've made that mistake many times before.)

