代码之家  ›  专栏  ›  技术社区  ›  Zach Langley

有趣的C++代码片段,有什么解释吗?[副本]

  •  0
  • Zach Langley  · 技术社区  · 6 年前


    Why am I able to make a function call using an invalid class pointer

    class B
    {
        public:
        int i;
        B():i(0){}
        void func1()
        {
            cout<<“func1::B\n”;
        }
        void func2()
        {
            cout<<“i = “<<i;
        } 
    };
    
    
    int main()
    {
    
        B *bp = new B;
    
        bp->func1();
    
        delete bp;
    
        bp = NULL;
    
        bp->func1();
        bp->func2();
    
        return 1; 
    }
    

    输出:

    func1::B 
    func1::B 
    Runtime Exception:
    NULL pointer access
    
    7 回复  |  直到 8 年前
        1
  •  7
  •   Matteo Italia    15 年前

    这是我的老故事 NULL (或无效的)对象指针;对于标准,调用 无效的 对象指针导致未定义的行为,这意味着,就标准而言,它可以很好地工作,它可以炸毁计算机或杀死一些随机的人。

    this 指针。

    无效的 ,所以它应该运行良好(就像 func1 ).

    func2 ),它将取消对 指针 无效的 ,将导致崩溃(取消对 无效的 指针(这也是未定义的行为,但通常会导致崩溃)。

    请注意,如果您调用的方法是虚拟的,则几乎可以肯定使用 无效的

    顺便说一句, void main() 不是标准的;应该是 int main() argv argc

        2
  •  5
  •   Jonathan Leffler    15 年前

    当代码准备编译时,结果是合理的。

    这个 func1() this ; func2() this->i 因此当 为空。

    严格地说,这是未定义的行为-任何事情都可能发生。但是核心转储或运行时异常是对特定错误最常见的响应之一。

        3
  •  1
  •   wheaties    15 年前

    什么事这么烦人?第一个输出正确。第二种未定义的行为。第三种方法是试图访问一个类中包含的信息,而这个类现在不存在。程序正确地识别它是一个空指针。

        4
  •  0
  •   jelford    15 年前

    bp->func1()不需要对类成员进行任何访问-在Java中,最好将其定义为静态。也许编译器正在内联函数?

        5
  •  0
  •   Tomas    15 年前

    这样想:

    您已经告诉编译器,任何实例都不需要任何空间,因此当它尝试使用变量“i”时,它不会存储在任何有意义的地方,程序将失败。因为您已将引用设为null,所以程序会在执行此操作之前提前捕获它。

        6
  •  0
  •   tru7    15 年前

        7
  •  0
  •   Klaim    15 年前

    从使用delete之后使用指针的位置开始, 你进入“未定义行为”区域

    因此,超出这一点的任何行为都依赖于编译器的实现,即使“看起来它是工作的”,也必须被认为是错误的。