为何C++中调用空指针关联函数未导致程序崩溃?
为什么空指针调用非虚成员函数没崩溃?
嘿,这个问题戳中了C++里一个很容易让人困惑的点——未定义行为的不确定性,以及成员函数的调用机制,咱们一个个说清楚:
1. 为什么Entity& _ref = *ptr;没崩溃?
首先要明确:解引用空指针(*ptr)属于C++标准定义的未定义行为。但未定义行为不等于“一定会立刻崩溃”,它的意思是标准不规定这段代码会产生什么结果——可能崩溃,可能输出乱码,甚至可能看起来完全正常运行。
在你的例子里,_ref只是绑定到了ptr指向的空地址,但这一步并没有实际去读取或写入那块内存的内容,所以很多编译器不会立刻触发崩溃。但这绝对不代表这段代码是合法的!
2. 为什么_ref->Print();能成功执行?
这就要说到非虚成员函数的调用逻辑了:
对于非虚成员函数,编译器在编译时就会确定它的地址,调用的时候其实是把对象的指针作为隐含的this参数传递给函数。比如_ref->Print();会被编译器转化成类似:
Entity::Print(&_ref);
而你的Print函数非常特殊:它是const的,而且没有访问任何类的成员变量,全程没用到this指针!
既然函数里根本没使用this(也就是那个nullptr),自然不会去访问非法内存,所以程序能正常输出字符串,不会崩溃。
3. 什么时候会崩溃?
如果你的Print函数尝试访问类的成员变量,比如:
class Entity { private: std::string m_Name = "Entity"; public: void Print() const { std::cout << m_Name << std::endl; } };
这时候Print里的m_Name其实是this->m_Name,就会通过nullptr去访问内存,这时候就会触发崩溃(比如段错误)。
最后提醒
虽然这次代码没崩溃,但这完全是侥幸!未定义行为是C++里的雷区,你永远不能依赖它的表现——换个编译器、换个平台,甚至只是优化等级变一下,这段代码可能立刻崩溃,或者出现更诡异的问题。千万不要这么写!
内容的提问来源于stack exchange,提问作者Yanshof
相关产品推荐
相关产品推荐

