0

在 Visual C++ 2010 下,以下代码片段隐藏了一个可疑行为:

CObject* myObjectPtr = CObjectFactory::MakeAnObject();
assert( myObjectPtr->CanDoSomeWork() ); // myObjectPtr can be null due to logical errors

下面的代码片段,当放在一个函数中时,当指针为 NULL 并且函数立即返回时,没有触发断言。除了额外的空指针检查任何人都可以建议的明显修复之外,是什么让代码以这种方式运行?即使错误发生在断言中,它通常不应该抱怨内存访问冲突错误吗?

4

2 回答 2

2
myObjectPtr->CanDoSomeWork()

如果 CanDoSomeWork 不是虚函数,则编译器有效地将其重写为 C_Object::CanDoSomeWork(myObjectPtr)

这根本不涉及对象指针的任何取消引用,因此它不会崩溃或失败。如果它是一个虚函数,那么它可能会崩溃,因为它将使用指针来查找 vtable。

当然,标准中的任何内容都不能保证这一切,这都是未定义的行为,但是它解释了您所看到的情况。

于 2013-04-25T10:53:32.410 回答
1
assert( myObjectPtr->CanDoSomeWork() );

myObjectPtr如果为 NULL,将导致段错误(或 UB) 。因为NULL->* 是未定义的行为。
您应该首先检查是否myObjectPtr不是 NULL 指针。

assert (myObjectPtr != 0);
assert( myObjectPtr->CanDoSomeWork() .....);  // if you still need this (?)
于 2013-04-25T08:58:36.503 回答