在使用指针之前检查null [英] Checking for null before pointer usage

查看:184
本文介绍了在使用指针之前检查null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大多数人都使用这样的指针...

  if(p!= NULL){
DoWhateverWithP );
}

但是,如果指针因为任何原因为空,



我的问题是,只是不检查NULL可能更有益吗?显然,在安全关键系统上,这不是一个选项,但是你的程序崩溃在一个荣耀比一个函数没有被调用,如果程序仍然可以运行没有它更明显。



关于第一个问题,你在使用指针之前总是检查NULL吗?



考虑你有一个函数接受一个指针作为参数,并且你的程序中多次使用这个函数的多个指针。你发现在函数中测试NULL更有好处(好处是你不必在整个地方测试NULL),或者在调用函数之前对指针进行测试(好处是没有调用函数的开销) )

解决方案

不要让它只是检查null,如果你找到它什么也不做。 >

如果指针允许为空,那么你必须考虑你的代码在实际上为null的情况下做什么。通常,只是什么也不做是错误的答案。小心的是可以定义API,这样的工作,但这不仅仅是散布几个NULL检查的地方。



所以,如果指针被允许为null,那么你必须检查null,并且你必须做任何适当的事情。



如果指针不允许为null,那么写代码是完全合理的如果它为null,则调用未定义的行为。这与编写字符串处理例程没有什么不同,如果输入不是NUL终止,则调用未定义的行为,或者如果调用者传递了错误的长度值,则编写调用未定义行为的缓冲区使用例程,或者编写一个函数a file * 参数,如果用户将文件描述符reinterpret_cast传递给 file * ,则调用未定义的行为。在C和C ++中,你只需要能够依赖于调用者告诉你的东西。垃圾,垃圾输出。



然而,你可能想编写代码,帮助你的调用者(谁可能是你,毕竟)当最可能的种类的垃圾



从Franci对这个问题的评论中得出类比:大多数人在越过一条小径时不寻找汽车,或在坐下他们的沙发之前。他们仍然可以打一辆车。它发生。但是,一般来说,在这种情况下花费任何努力来检查汽车,或者为了汤的说明首先,检查你厨房里的汽车,然后加热汤,通常会被视为偏执。



代码也是如此。将一个无效的值传递给一个函数要容易得多,而不是意外地将你的汽车驶入某人的厨房。但它仍然是司机的错,如果他们这样做,打某人,而不是厨师的失败,适当照顾。你不一定希望厨师(或被调教者)用他们的食谱(代码)来填补应该是多余的检查。



还有其他方法来找到问题,例如单元测试和调试器。在任何情况下,创建一个无车的环境除非在必要(道路),比驱动汽车在所有地方,并希望每个人都能在任何时候应付他们,是更安全。因此,如果您在不允许的情况下检查null,您不应该让此人给予 所有允许的想法。




Most people use pointers like this...

if ( p != NULL ) {
  DoWhateverWithP();
}

However, if the pointer is null for whatever reason, the function won't be called.

My question is, could it possibly be more beneficial to just not check for NULL? Obviously on safety critical systems this isn't an option, but your program crashing in a blaze of glory is more obvious than a function not being called if the program can still run without it.

In relation to the first question, do you always check for NULL before you use pointers?

Secondly, consider you have a function that takes a pointer as an argument, and you use this function multiple times on multiple pointers throughout your program. Do you find it more beneficial to test for NULL in the function (the benefit being you don't have to test for NULL all over the place), or on the pointer before calling the function (the benefit being no overhead from calling the function)?

解决方案

Don't make it a rule to just check for null and do nothing if you find it.

If the pointer is allowed to be null, then you have to think about what your code does in the case that it actually is null. Usually, just doing nothing is the wrong answer. With care it's possible to define APIs which work like that, but this requires more than just scattering a few NULL checks about the place.

So, if the pointer is allowed to be null, then you must check for null, and you must do whatever is appropriate.

If the pointer is not allowed be null, then it's perfectly reasonable to write code which invokes undefined behaviour if it is null. It's no different from writing string-handling routines which invoke undefined behaviour if the input is not NUL-terminated, or writing buffer-using routines which invoke undefined behaviour if the caller passes in the wrong value for the length, or writing a function that takes a file* parameter, and invokes undefined behaviour if the user passes in a file descriptor reinterpret_cast to file*. In C and C++, you simply have to be able to rely on what your caller tells you. Garbage in, garbage out.

However, you might like to write code which helps out your caller (who is probably you, after all) when the most likely kinds of garbage are passed in. Asserts and exceptions are good for this.

Taking up the analogy from Franci's comment on the question: most people do not look for cars when crossing a footpath, or before sitting down on their sofa. They could still be hit by a car. It happens. But it would generally be considered paranoid to spend any effort checking for cars in those circumstances, or for the instructions on a can of soup to say "first, check for cars in your kitchen. Then, heat the soup".

The same goes for your code. It's much easier to pass an invalid value to a function than it is to accidentally drive your car into someone's kitchen. But it's still the fault of the driver if they do so and hit someone, not a failure of the cook to exercise due care. You don't necessarily want cooks (or callees) to clutter up their recipes (code) with checks that ought to be redundant.

There are other ways to find problems, such as unit tests and debuggers. In any case it is much safer to create a car-free environment except where necessary (roads), than it is to drive cars willy-nilly all over the place and hope everybody can cope with them at all times. So, if you do check for null in cases where it isn't allowed, you shouldn't let this give people the idea that it is allowed after all.

[Edit - I literally just hit an example of a bug where checking for null would not find an invalid pointer. I'm going to use a map to hold some objects. I will be using pointers to those objects (to represent a graph), which is fine because map never relocates its contents. But I haven't defined an ordering for the objects yet (and it's going to be a bit tricky to do so). So, to get things moving and prove that some other code works, I used a vector and a linear search instead of a map. That's right, I didn't mean vector, I meant deque. So after the first time the vector resized, I wasn't passing null pointers into functions, but I was passing pointers to memory which had been freed.

I make dumb errors which pass invalid garbage approximately as often as I make dumb errors which pass null pointers invalidly. So regardless of whether I add checking for null, I still need to be able to diagnose problems where the program just crashes for reasons I can't check. Since this will also diagnose null pointer accesses, I usually don't bother checking for null unless I'm writing code to generally check the preconditions on entry to the function. In that case it should if possible do a lot more than just check null.]

这篇关于在使用指针之前检查null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆