Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+中未定义的行为+;断言:访问无效/空指针 在Visual C++ 2010下,下面的片段隐藏了一个可疑的行为: CObject* myObjectPtr = CObjectFactory::MakeAnObject(); assert( myObjectPtr->CanDoSomeWork() ); // myObjectPtr can be null due to logical errors_C++_Visual Studio 2010_Assert - Fatal编程技术网

C+中未定义的行为+;断言:访问无效/空指针 在Visual C++ 2010下,下面的片段隐藏了一个可疑的行为: CObject* myObjectPtr = CObjectFactory::MakeAnObject(); assert( myObjectPtr->CanDoSomeWork() ); // myObjectPtr can be null due to logical errors

C+中未定义的行为+;断言:访问无效/空指针 在Visual C++ 2010下,下面的片段隐藏了一个可疑的行为: CObject* myObjectPtr = CObjectFactory::MakeAnObject(); assert( myObjectPtr->CanDoSomeWork() ); // myObjectPtr can be null due to logical errors,c++,visual-studio-2010,assert,C++,Visual Studio 2010,Assert,下面的代码段放在函数中时,当指针为NULL且函数立即返回时,不会触发断言。除了任何人都可以建议的一个额外的空指针检查明显的修复之外,是什么让代码以这种方式运行?即使在断言中发生内存访问冲突错误,它也应该抱怨内存访问冲突错误吗 assert( myObjectPtr->CanDoSomeWork() ); 如果myObjectPtr为空,将导致segfault(或UB)。因为NULL->*是未定义的行为。 您应该首先检查myObjectPtr是否不是空指针 assert (myObject

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

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

assert (myObjectPtr != 0);
assert( myObjectPtr->CanDoSomeWork() .....);  // if you still need this (?)
如果
myObjectPtr
为空,将导致segfault(或UB)。因为
NULL->
*是未定义的行为。
您应该首先检查
myObjectPtr
是否不是空指针

assert (myObjectPtr != 0);
assert( myObjectPtr->CanDoSomeWork() .....);  // if you still need this (?)
如果CanDoSomeWork不是一个虚拟函数,那么编译器会有效地将其重写为 C_对象::CanDoSomeWork(myObjectPtr)

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

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

如果CanDoSomeWork不是一个虚拟函数,那么编译器会有效地将其重写为 C_对象::CanDoSomeWork(myObjectPtr)

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



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

这是明显的未定义行为。所以任何事情都有可能发生。试图找出某个特定“某事”发生的原因没有什么意义。
assert(true)
是否引发了任何问题?@Elazar,是的,它在调试模式下运行,在“正常”情况下启用并触发assert。s@juanchopanza谢谢,我想那一定是不确定的行为,但是,在这一点上,我花了将近一个月的时间在所有错误的地方搜索bug源,我想防止以后即使是这种笨拙的错误也会花费超过几分钟的调试时间(因此,更好地理解原因的动机——VS2010应该对此有一个特定的实现规范——可能与其他编译器不同)。CanDoSomeWork在做什么?它是否访问CObject*成员?它显然是未定义的行为。所以任何事情都有可能发生。试图弄清楚为什么会出现特定的“某物”是毫无意义的Occessed.does
assert(true)
引发任何问题?@Elazar,是的,它在调试模式下运行,断言已启用,并在“正常”情况下触发。s@juanchopanza谢谢,我发现这一定是未定义的行为,但这一点花了我将近一个月的时间在所有错误的地方搜索错误源,我想防止这种笨拙的错误避免在将来花费超过几分钟的调试时间(因此,更好地理解原因的动机-VS2010应该对此有一个特定的实现规范-可能与其他编译器不同)CanDoSomeWork正在做什么?它是否访问了CopEdj**成员?是的,这是我第二次意识到正在发生的事情的明显方向。但是假设你考虑一个指针是一致的,而忽略第一个断言,那么第二个断言可能不会像预期的那样崩溃应用程序,并且完全隐藏一个关键错误。ly!如果它总是segafault就好了。但有时可能不是。未定义的行为。因此,在尝试遵从或间接引用指针之前,应该始终检查指针是否为null。Re:“segafault(或UB)”形式上,行为是未定义的。这意味着语言定义并没有告诉你发生了什么;它并不意味着坏事必须发生。未定义的行为通常表现为分段错误,但它经常不发生。是的,这是第二次我意识到正在发生的事情的明显方向。但是假设你考虑了一个指针。要保持一致并省略第一个断言,则第二个断言可能不会按预期使应用程序崩溃并完全隐藏一个严重错误。@teodron是的,完全正确!如果它总是出错,那就太好了。但有时可能不是。未定义的行为。因此,在尝试定义之前,您应该始终检查指针是否为null删除它们或间接删除它们。Re:“segfault(或UB)”-从形式上讲,行为是未定义的。这意味着语言定义不会告诉您发生了什么;这并不意味着坏事一定会发生。未定义的行为通常表现为segfault,但通常不会。事实上,它是一个非虚拟函数-感谢您的解释。从形式上讲,调用非静态成员函数是对对象指针的取消引用。这会导致未定义的行为。它是否崩溃、失败或是否像您预期的那样工作取决于编译器。是的,的确如此。在大多数编译器上,它恰好是这样工作的,因为这是实现它的最简单和明显的方法。永远不要依赖它这样工作!@jcoder,即使它是c按照显而易见的方式,如果系统将地址0映射到有效内存,则不会发生故障。幸运的是,大多数平台都没有这样做,以帮助程序员捕获错误。事实上,这是一个非虚拟函数-感谢您的解释。从形式上讲,调用非静态成员函数是对对象指针的取消引用。这会导致未定义ed行为。它是否崩溃或失败,或者看起来是否像您预期的那样工作,取决于编译器。是的,的确如此。在大多数编译器上,它恰好是这样工作的,因为它是