在 C++ 中使用对象之前始终检查空指针是一种良好的编程习惯吗?

发布于 2024-09-01 01:35:33 字数 102 浏览 5 评论 0原文

这看起来工作量很大;每次使用对象时检查 null 。

有人建议我检查空指针是个好主意,这样您就不必花时间寻找发生分段错误的位置。

只是想知道这里的社区怎么想?

This seems like a lot of work; to check for null each time an object is used.

I have been advised that it is a good idea to check for null pointers so you don't have to spend time looking for where segmentation faults occur.

Just wondering what the community here thinks?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

赏烟花じ飞满天 2024-09-08 01:35:33

尽可能使用引用,因为它们不能为空,因此您不必检查它们是否为空。

最好检查函数参数中以及您可能正在处理其他人传递给您的指针的其他地方是否为空。但是,在您自己的代码中,您可能知道指针始终指向有效对象,因此空检查可能有点过大……只需使用您的常识即可。

我不知道它是否真的有助于调试,因为任何调试器都会非常清楚地向您显示使用了空指针,并且不需要很长时间就能找到它。更多的是要确保如果另一个程序员传入 NULL,或者错误被调试版本中的断言发现,您不会崩溃。

Use references whenever you can, because they can't be null, therefore you don't have to check if they are null.

It's good practice to check for null in function parameters and other places you may be dealing with pointers someone else is passing you. However, in your own code, you might have pointers you know will always be pointing to a valid object, so a null check is probably overkill... just use your common sense.

I don't know if it really helps with debugging because any debugger will be showing you pretty clearly that a null pointer was used and it won't take long to find it. It's more about making sure you don't crash if another programmer passes in NULL, or that the mistake is picked up by an assert in a debug build.

海风掠过北极光 2024-09-08 01:35:33

不。您应该首先确保指针没有设置为 NULL。请注意,在标准 C++ 中:

int * p = new int;

p 永远不能为 NULL,因为如果分配失败,new 将抛出异常。

如果您正在编写可以将指针作为参数的函数,您应该像这样对待它们。

// does something with p
// note that p cannot be NULL
void f( int * p );

换句话说,您应该记录函数的要求。你还可以使用assert()来检查是否有人忽略了你的文档(如果他们忽略了,那是他们的问题,而不是你的),但我必须承认,随着时间的推移,我已经不再这样做了——简单地说一下函数需要什么,并将责任留给调用者。

第三个建议就是不要使用指针——我见过的大多数 C++ 代码过度使用指针到了荒谬的程度——你应该尽可能使用值和引用。

No. You should instead make sure the pointers were not set to NULL in the first place. Note that in Standard C++:

int * p = new int;

then p can never be NULL because new will throw an exception if the allocation fails.

If you are writing functions that can take a pointer as a parameter, you should treat them like this

// does something with p
// note that p cannot be NULL
void f( int * p );

In other words you should document the requirements of the function. You can also use assert() to check if someone has ignored your documentation (if they have, it's their problem, not yours), but I must admit I have gone off this as time has gone on - simply say what the function requires, and leave the responsibility with the caller.

A third bit of advice is simply not to use pointers - most C++ code that I've seen overuses pointers to a ridiculous extent - you should use values and references wherever possible.

睫毛上残留的泪 2024-09-08 01:35:33

一般来说,我建议不要这样做,因为它会使代码更难阅读,并且如果指针实际上为 NULL,您还必须想出一些明智的方法来处理这种情况。

在我的 C++ 项目中,我仅检查指针(如果我使用指针)是否为 NULL,前提是它可能是指针的有效状态。如果指针实际上不应该为 NULL,则检查 NULL 有点毫无意义,因为您随后会尝试解决一些应该修复的编程错误。

此外,当您觉得需要检查指针是否为 NULL 时,您可能应该更清楚地定义谁拥有指针/对象。

另外,您永远不必检查 new 是否返回 NULL,因为它永远不会返回 NULL。如果无法创建对象,它将抛出异常。

In general, I would advise against doing this, as it makes your code harder to read and you also have to come up with some sensible way of dealing with the situation if a pointer is actually NULL.

In my C++ projects, I only check if a pointer (if I am using pointers at all) is NULL, only if it could be a valid state of the pointer. Checking for NULL if the pointer should never actually be NULL is a bit pointless, because you are then trying work around some programming error you should fix instead.

Additionally, when you feel the need to check if a pointer is NULL, you probably should define more clearly who owns pointer/object.

Also, you never have to check if new returns NULL, because it never will return NULL. It will throw an exception if it could not create an object.

ヅ她的身影、若隐若现 2024-09-08 01:35:33

我讨厌添加大量代码检查空值,因此我只对导出给另一个人的函数执行此操作。

如果在内部使用该函数,并且我知道如何使用它,我不会检查空值,因为它会使代码太混乱。

I hate the amount of code checking for nulls adds, so I only do it for functions I export to another person.

If use the function internally, and I know how I use it, I don't check for nulls since it would get the code too messy.

十级心震 2024-09-08 01:35:33

答案是肯定的,如果你无法控制该物体。也就是说,如果该对象是从您无法控制的某个方法返回的,或者在您自己的代码中您期望(或可能)对象可以为 null。

它还取决于代码将在哪里运行。如果您正在编写客户/用户会看到的专业代码,那么他们看到空指针问题通常是不好的。如果您可以事先检测到它并打印出一些调试信息或以“更好”的方式向他们报告,那就更好了。

如果它只是您非正式使用的代码,您可能无需任何其他信息就能够理解空指针的来源。

the answer is yes, if you are not in control of the object. that is, if the object is returned from some method you do not control, or if in your own code you expect (or it is possible) that an object can be null.

it also depends on where the code will run. if you are writing professional code that customers / users will see, it's generally bad for them to see null pointer problems. it's better if you can detect it beforehand and print out some debugging information or otherwise report it to them in a "nicer" way.

if it's just code you are using informally, you will probably be able to understand the source of the null pointer without any additional information.

分开我的手 2024-09-08 01:35:33

我认为我可以对 NULL 指针进行大量检查,而只需花费(调试)一个段错误的成本。

而且对性能的影响可以忽略不计。两个说明。测试寄存器 == 0,如果测试成功则转移。根据机器的不同,如果寄存器加载设置了条件代码(有些确实如此),则可能只有一条指令。

I figure I can do a whole lot of checks for NULL pointers for the cost of (debugging) just one segfault.

And the performance hit is negligible. TWO INSTRUCTIONS. Test for register == zero, branch if test succeeds. Depending on the machine, maybe only ONE instruction, if the register load sets the condition codes (and some do).

毁虫ゝ 2024-09-08 01:35:33

其他人(AshleysBrain 和 Neil Butterworth)已经正确回答了,但我将在这里总结一下:

  1. 尽可能使用引用
  2. 如果使用指针,请将它们初始化为 NULL 或有效的内存地址/对象
  3. 如果使用指针,请始终验证它们是否在使用它们之前为 NULL
  4. 使用引用(再次)...这是 C++,而不是 C。

不过,有一种极端情况,引用可能无效/NULL:

void foo(T & t)
{
   t.blah() ;
}

void bar()
{
   T * t = NULL ;
   foo(*t) ;
}

编译器可能会编译它,然后在执行时,代码将在 t.blah() 行崩溃(如果 T::blah() 以某种方式使用 this)。

不过,这仍然是作弊/破坏:bar() 函数的编写者在未验证 t 不为空的情况下取消引用了 t。因此,即使崩溃发生在 foo() 中,错误也出在 bar() 的代码中,并且 bar() 的编写者> 负责。

所以,是的,尽可能多地使用引用,了解这个极端情况,并且不必费心去防止引用被破坏......

如果你确实需要在 C++ 中使用指针,除非你如果 100% 确定该指针不为 NULL(某些函数可以保证这种情况),那么请始终测试该指针。

Others (AshleysBrain and Neil Butterworth), already answered correctly, but I will summarize it here:

  1. Use references as much as possible
  2. If using pointers, initialize them either to NULL or to a valid memory address/object
  3. If using pointers, always verify if they are NULL before using them
  4. Use references (again)... This is C++, not C.

Still, there is one corner case where a reference can be invalid/NULL :

void foo(T & t)
{
   t.blah() ;
}

void bar()
{
   T * t = NULL ;
   foo(*t) ;
}

The compiler will probably compile this, and then, at execution, the code will crash at the t.blah() line (if T::blah() uses this one way or another).

Still, this is cheating/sabotage : The writer of the bar() function dereferenced t without verifying t was NOT null. So, even if the crash happens in foo(), the error is in the code of bar(), and the writer of bar() is responsible.

So, yes, use references as much as possible, know this corner case, and don't bother to protect against sabotaged references...

And if you really need to use a pointer in C++, unless you are 100% sure the pointer is not NULL (some functions guarantee that kind of thing), then always test the pointer.

伊面 2024-09-08 01:35:33

我认为这对于调试版本来说是个好主意。
在发布版本中,检查空指针可能会导致性能下降。
此外,在某些情况下,您可以检查父函数中的指针值并避免检查其子函数。

I think that is a good idea for a debug version.
In a release version, checking for null pointers can result in a performance degradation.
Moreover, there are cases where you can check the pointer value in a parent function and avoid the checking in its children.

小镇女孩 2024-09-08 01:35:33

如果指针作为函数的参数传给您,请确保它们在函数的开头是有效的。否则,就没有太多意义。 new 失败时抛出异常。

If the pointers are coming to you as parameters to a function, then make sure they are valid at the beginning of the function. Otherwise, there is not much point. new throws an exception on failure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文