面试中会有这样的题目,实际项目也有人遭过!是什么呢,就是类对象被释放后,还可以访问class成员函数,因为编译过了,运行中没有check null就会直接调用,下面我们可以看看奇葩的两种用法。
#include
class test{
public:
void print(){
printf("%s\n",__FUNCTION__ );
}
#include
class test{
public:
test():m_Val(0){
}
void print(){
printf("%s\n",__FUNCTION__ );
}
void funusemem(){
printf("%s\n",__FUNCTION__ );
printf("m_Val is :%d\n", m_Val);
}
private:
int m_Val;
};
int main(){
test* p = new test;
delete p;
p = NULL;
int* m = new int;
((test*)m)->funusemem();
p->funusemem();
return 0;
}
他们都成功调用了print函数.
那再让我们看看另外一种会挂掉的用法:
#include
class test{
public:
test():m_Val(0){
}
virtual void print(){
printf("%s\n",__FUNCTION__ );
}
void funusemem(){
printf("%s\n",__FUNCTION__ );
printf("m_Val is :%d\n", m_Val);
}
private:
int m_Val;
};
int main(){
test* p = new test;
delete p;
p = NULL;
int* m = new int(1998);
((test*)m)->funusemem();
p->funusemem();
return 0;
}
第一个仍然不会挂,第二个会挂,特么很诡异吧,第二个挂的原因是this指针为NULL会segmentation fault.
第一个不仅不会错误,而且输出了1998,哈哈,这就是C++ class的调用机制,你看到木有,因为这里没有virtual table,所以第一个mem直接是*(int*)this,所以这里不会有问题,如果有虚函数肯定就会错!(这个已测试)
所以C++坑还是比较多的,可以多踩踩,特么才知道oh shit!