如何在取消引用空指针时创建错误?

问题描述:

下面的代码编译没有错误和不分段故障运行:如何在取消引用空指针时创建错误?

int* a = 0; 
int& b = *a; 

我们确实有在参考一空指针。这个引用可能会在项目中移动一段时间直到它被使用。当它被使用时会产生分段错误。

目前使用的编译器是MSVC 10.0和gcc 4.9。 为了简化对错误的查找,我希望解引用在空指针上失败,以便在上述代码中引起段错误。是否有可能实现这一点以及如何实现?

+1

解除引用空指针会导致[*未定义行为*](http://en.cppreference.com/w/cpp/language/ub),有时UB可能实际上*看起来*工作。编译器也可能优化了代码。只要你有UB,就不可能说任何其他的东西,或者预测一些事情。 –

+0

当在调试模式下运行时,您最喜欢的ide会给出错误的位置。 – dani

+1

考虑使用std :: optional而不是指针和引用。 – 2017-08-02 13:18:24

与海湾合作委员会,你有消毒液是一个标志,让编译器添加一些代码,导致崩溃,当您尝试访问无效的地址(该地址出界,空指针,...)。

您可以在gcc's documentation for instrumentation中搜索-fsanitize=address

使用清洁剂(使用gcc)时,您必须链接到清洁剂。 例如:

g++ -fsanitize=address -c -o file.o file.cpp 
g++ -o a.out file.o -fsanitize=address 

我不认为MSVC有类似的机制。

+0

我尝试了一个小例子,它不会将错误移动到另一个地方,但会给出增强的错误消息。 [link](https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm)上的文件指出,操作员已被更换。我预计这个错误发生在贬值本身。 – Davidius

您的代码的行为是undefined

您可能不会必然得到一个分段错误(编译器甚至可能优化出错的语句),所以不要在可移植C++中依赖此技术。

如果你想你的程序崩溃,然后使用​​,或std::terminate();

如果你想测试NULL的含量指针ptr然后使用

if (!ptr){ 
    // ptr is nullptr 
} 

参考文献:

http://en.cppreference.com/w/cpp/utility/program/abort http://en.cppreference.com/w/cpp/error/terminate

+1

我的印象是,OP正在寻找一个编译器标志或一个分析工具来捕捉这些类型的错误 – bolov

+1

@bolov那么他至少应该提及哪个编译器,他应该不会? – Slava

+0

他想要一种自动捕获这类错误的方法,类似于如何访问null将在java中引发NullPointerException异常 – bolov

为了缓解错误的发现,我希望解引用在空指针上失败,以便在上述代码中引起段错误。是否有可能实现这一点以及如何实现?

在您提到的代码片段中没有实际的解除引用 - 我的意思是在定义引用时没有必要访问内存。但情况更糟 - 即使您开始使用该引用编译器,C++标准没有义务检查nullptr,因此没有可自动检查的便携式方法。只有便携的方式 - 提供代码手动验证它:

int* a = 0; 
assert(a); 
int& b = *a; 

这种方式,您将验证在调试模式的正确性,也不会在发布此代码。或者你可以把代码总是检查它。要点是 - 您有责任决定是否愿意支付验证指针的价格。一些编译器虽然可以选择启用nullptr检测,但您应该依赖于编译器文档。但这种方式根本不可移植。甚至当你使用该标志时,也没有保证当你声明参考时(尤其是启用优化时)会发生这种验证。

补充拔示巴的回答是:

你可以把这些代码一个try-catch语句内,当指针是nullptr,然后做一些事情引发异常。例如

enum PointerException { 
    NullReference = 1 
}; 

然后是这样的:

try { 
    if(!ptr) { 
     //Your pointer ain't null, do something. 
    } else { 
     //Your pointer is null, raise an exception. 
     throw PointerException::NullReference; 
    } 
} catch(PointerException exception) { 
    //Do something with your exception 
} 
+0

我宁愿抛出类似'struct NullReference {};'的东西,并抛出它,所以你可以在捕获网站时更少含糊。 – Bathsheba