在Visual C ++ 2010下,以下代码段隐藏了一个可疑的行为:
CObject* myObjectPtr = CObjectFactory::MakeAnObject();
assert( myObjectPtr->CanDoSomeWork() ); // myObjectPtr can be null due to logical errors
当放置在函数中时,下面的代码段在指针为NULL并且函数立即返回时没有触发断言。除了一个额外的空指针检查任何人都可以建议的明显修复,是什么使代码以这种方式运行?即使在断言中发生错误,它通常不应该抱怨内存访问冲突错误吗?
答案 0 :(得分:2)
myObjectPtr->CanDoSomeWork()
如果CanDoSomeWork不是虚函数,则编译器会将其重写为 C_Object :: CanDoSomeWork(myObjectPtr)
这根本不涉及对象指针的任何取消引用,因此它不会崩溃或失败。 如果它是一个虚函数,那么它可能会崩溃,因为它将使用指针来查找vtable。
当然,标准中的任何内容都不能保证这一点,这是所有未定义的行为,但它解释了您所看到的情况。
答案 1 :(得分:1)
assert( myObjectPtr->CanDoSomeWork() );
如果myObjectPtr
为NULL,将导致segfault(或UB)。因为NULL->
*是未定义的行为
您应该首先检查myObjectPtr
是否不是NULL指针。
assert (myObjectPtr != 0);
assert( myObjectPtr->CanDoSomeWork() .....); // if you still need this (?)