セキュアコーディングについて勉強しています。
次のページの 2 番目のコード例では、"skip" 変数に (char *) を使用することを推奨しています。 https://www.securecoding.cert.org/confluence/display/seccode/EXP08-C.+Ensure+pointer+arithmetic+is+used+correctly
この例のアドレス計算についてはよくわかりません。だから私は次のコードを作りました。
#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;
}
以下の両方が間違ったアドレスを返すようです。
1) getAdrs(s + スキップ); // オリジナルの非準拠コード
2) getAdrs((char *)s + スキップ); // おすすめ
この場合、ul1_2 は struct big の先頭から数えて 8 バイト目にあるので、((struct big の先頭アドレス) + 0x08) が得られると思います。そうですか?ただし、上記のケース2は(構造体bigの先頭アドレス+ 0x02)を返すようです。
私は正しいですか、それともアドレスに関する私の理解が間違っていますか?