c++断言中的未定义行为:访问无效/空指针



在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 (?)

相关内容

  • 没有找到相关文章

最新更新