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

时间:2013-04-25 08:56:51

标签: c++ visual-studio-2010 assert

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

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

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

2 个答案:

答案 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 (?)