我正在研究安全编码.
在下一页的第二个代码示例中,建议使用(char*)表示"skip"变量. 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;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,以下两个都返回错误的地址.
1)getAdrs(s + skip); //原始的不合规代码
2)getAdrs((char*)s + skip); //推荐
在这种情况下,我认为(结构大的头部地址)+ 0x08)应该被获得,因为ul1_2位于从struct big的头部开始计数的第8个字节.这样对吗?但是,上面的情况2似乎返回(struct big的头地址+ 0x02).
我是正确的,还是我对地址的理解不正确?
你是绝对正确的!你的代码也是如此!唯一不对的是......你的十六进制数学.:)
getAdrs(s ); // 0x9a38008
getAdrs(s + skip ); // 0x9a38108 (+256)
getAdrs((char *)s + skip); // 0x9a38010 (+2)
>>> print 0x9a38010 - 0x9a38008
8
Run Code Online (Sandbox Code Playgroud)
(老实说,不要感觉不好.在我看到它之前,我花了五分钟时间盯着它和链接的文档.我之前已经犯了很多次错误.)