You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何未通过new关键字实例化的类指针执行delete后仍能成功调用成员函数?

为什么这段代码能"成功"调用f()?

这问题其实戳中了C++里成员函数调用的底层逻辑,还有未定义行为的特殊性,咱们一步步拆解:

1. 非虚成员函数的调用不依赖对象的实际内存

先看你的f()函数:它是非虚成员函数,而且里面完全没有访问类的成员变量——只是输出一个固定字符串。

在C++里,非虚成员函数是静态绑定的,编译器在编译阶段就确定了函数的调用地址。当你写b->f()时,编译器会偷偷把它转换成类似A::f(b)的形式:把指针b作为隐式的this参数传递给f()。

因为f()根本没用到this指针(不需要读取对象内存),所以哪怕b是个野指针,函数也能正常执行——它只是跑一段固定的代码而已,和b指向的内存有没有效没关系。

2. 关于delete b的行为

首先,A* b;这行只声明了指针,没初始化,所以b是个野指针,指向内存里的随机地址。

对野指针执行delete是标准定义的未定义行为——这意味着什么都可能发生:可能立刻崩溃,可能啥反应都没有,甚至可能悄悄破坏其他内存数据。你的代码里delete b后没崩,纯粹是运气好(或者说倒霉,因为这种未定义行为会埋下巨大隐患),但这绝对不是合法操作。

3. 这绝对不是正确的代码!

虽然你的代码看起来"运行成功"了,但完全是依赖未定义行为的巧合。如果给A加个成员变量,让f()访问它:

class A{
private:
    int x = 10;
public:
    void f(){cout<<"f, x="<<x;}
};

再运行b->f()大概率会直接崩溃——因为此时函数需要通过this指针读取x,而this是野指针,指向的内存完全无效。

另外,未初始化指针、随意delete野指针都是极度危险的操作,实际项目里必须彻底避免——它们会导致难以排查的内存错误、程序崩溃甚至安全问题。

内容的提问来源于stack exchange,提问作者Sachin Palande

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 19:32:36