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