检测不了的错误(2) --- 分析

为什么编译和运行时都不能检测到这个问题呢. 为什么一个空指针还能够调用对象的成员函数呢? 我们要看看汇编代码. MyClass::Foo() 其实是一个全局函数, 在符号表中的名字是 "_ZN7MyClass2FooEv". 所以调用时并不需要通过对象指针. 不过在调用这个函数时,会传递对象指针进去. 函数的定义: .globl _ZN7MyClass3FooEv .type _ZN7MyClass3FooEv, @function _ZN7MyClass3FooEv: .LFB1442: pushl %ebp .LCFI4: movl %esp, %ebp .LCFI5: subl $8, %esp .LCFI6: subl $8, %esp pushl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ subl $12, %esp pushl $.LC0 pushl $_ZSt4cout .LCFI7: call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc addl $20, %esp pushl %eax .LCFI8: call _ZNSolsEPFRSoS_E addl $16, %esp leave ret 函数的调用: ptr = NULL; ptr->Foo(); return 0; 对应的汇编 movl $0, -4(%ebp) ;; ptr = NULL; subl $12, %esp ;; 通过堆栈进行参数传递,传入ptr. 不过Foo()没有用到它. pushl -4(%ebp) ;; call _ZN7MyClass3FooEv ;; ptr->Foo() addl $16, %esp movl $0, %eax ;; return 0 leave ret 通过上面的分析,我们明白了为什么这个让人迷惑的语句可以通过编译和运行了. 如果Foo()访问对象的成员,那么肯定是会出错的. 因为Foo()需要使用传入的ptr,而ptr的值是NULL. 比如 void Foo() { cout<<"MyClass::Foo() is invoked!"< <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值