网站怎么做才能赚钱吗,郑州网站怎么推广,如何搭建一个自己上传视频的网站,东莞网站设计找谁可能有些朋友看见这个标题第一反应是嵌入式的某些内存中,0地址也是可以被正常访问的,所以对0地址的解引用不会发生错误,但我要说的情况不是这个,而是指一个真正的空指针,不仅是c/c中的0,(void*)0,NULL,还有nullptr,一个真正的空指针.
在c语言中,想获得某结构体的成员变量相对偏…可能有些朋友看见这个标题第一反应是嵌入式的某些内存中,0地址也是可以被正常访问的,所以对0地址的解引用不会发生错误,但我要说的情况不是这个,而是指一个真正的空指针,不仅是c/c中的0,(void*)0,NULL,还有nullptr,一个真正的空指针.
在c语言中,想获得某结构体的成员变量相对偏移,可以使用offsetof宏,其实现可能是:
#define offsetof(s,m) (size_t)(((s*)0)-m)可以发现:
先将0转换为指向s的指针使用-解引用,获取到m变量使用取地址,获得一个指向m的指针将指针转换为size_t,即为m的偏移
从这个例子可以发现,对于0地址,发生了一次解引用,然而并没有segmentation fault,为什么呢?其实呢,这个解引用被优化了,编译器看到这句时,并没有发生实际的解引用而获得到了m的地址,是一个真正的编译器开洞才能实现的功能.(如有错误,诚请斧正)
你可以这样定义自己的offsetof
#undef offsetof
#define offsetof(s,m) (size_t)(((s*)NULL)-m)
// 或
#undef offsetof
#define offsetof(s,m) (size_t)(((s*)nullptr)-m)你会发现,也是可以正常工作的,至少gcc的c14之前是可以的,gcc的c14后, 对于non-POD类型,这个宏将可能可能导致未定义的问题.注意,在cppreference中说的是从c11开始,对于non-POD类型使用offsetof宏将导致未定义行为.
gcc中的offsetof是这样定义的:
#define offsetof(type, member) __builtin_offsetof (type, member)可以发现,果然是内置的编译器开洞实现的功能.
综上,解引用一个空指针,不一定会导致段错误. 在c中,想获得类或结构体成员的偏移量,不要使用offsetof,而应该使用ClassName::MembersName,例如test::str,就获取到了str的偏移
#include vector
#include iostream
class test{
public:float float_number 3.14;int int_number 456;std::string str 789;
};templatetypename T
void print_member(const test* class_ptr,T test::* member_offset){printf(offset of member is %p,content is ,member_offset);std::cout class_ptr-*member_offset std::endl;
}int main(){test t;print_member(t,test::int_number);print_member(t,test::str);
}
/*
output:
offset of member is 0x4,content is 456
offset of member is 0x8,content is 789
*/