Mar*_*som 139 c++ null pointers dynamic-allocation
我首先要说的是,使用智能指针,你永远不必担心这一点.
以下代码有什么问题?
Foo * p = new Foo;
// (use p)
delete p;
p = NULL;
Run Code Online (Sandbox Code Playgroud)
这是由另一个问题的回答和评论引发的.Neil Butterworth的一条评论产生了一些赞成:
在删除后将指针设置为NULL不是C++中的通用优良做法.有时候它是一件好事,有时它是毫无意义的,可以隐藏错误.
有很多情况下它无济于事.但根据我的经验,它不会伤害.有人开导我.
Håv*_*d S 80
将指针设置为0(在标准C++中为"null",从C定义的NULL定义有些不同)避免了双删除时的崩溃.
考虑以下:
Foo* foo = 0; // Sets the pointer to 0 (C++ NULL)
delete foo; // Won't do anything
Run Code Online (Sandbox Code Playgroud)
鉴于:
Foo* foo = new Foo();
delete foo; // Deletes the object
delete foo; // Undefined behavior
Run Code Online (Sandbox Code Playgroud)
换句话说,如果你没有将删除的指针设置为0,如果你正在进行双重删除,你将遇到麻烦.反对在删除后将指针设置为0的参数是这样做只是掩盖双删除错误并使它们未处理.
显然,最好不要有双重删除错误,但根据所有权语义和对象生命周期,这在实践中很难实现.我更喜欢UB上的蒙面双删除错误.
最后,关于管理对象分配的旁注,我建议您根据需要查看std::unique_ptr严格/单一所有权,std::shared_ptr共享所有权或其他智能指针实现.
jal*_*alf 54
在删除它指向的内容之后将指针设置为NULL肯定不会受到伤害,但是对于一个更基本的问题,它通常是一个创可贴:为什么你首先使用指针?我可以看到两个典型的原因:
std::vector工作的,它解决了意外地将指针留给解除分配的内存的问题.没有指针.new可能与delete调用的指针不同.在此期间,多个对象可能同时使用了该对象.在这种情况下,共享指针或类似的东西本来是更可取的.我的经验法则是,如果你在用户代码中留下指针,你就是在做错了.指针不应该首先指向垃圾.为什么没有一个对象负责确保其有效性?为什么它的范围在指向对象时不会结束?
Don*_*eld 42
我有一个更好的最佳实践:在可能的情况下,结束变量的范围!
{
Foo* pFoo = new Foo;
// use pFoo
delete pFoo;
}
Run Code Online (Sandbox Code Playgroud)
Adr*_*thy 30
在删除它指向的对象后,我总是设置指向NULL(现在nullptr)的指针.
它可以帮助捕获许多对释放内存的引用(假设您的平台在空指针的deref上出错).
例如,如果你有指针的副本,它将不会捕获所有对freed内存的引用.但有些人比没有人好.
它将掩盖双重删除,但我发现这些远远不如访问已释放的内存.
在许多情况下,编译器将优化它.因此,不必要的说法并不能说服我.
如果你已经在使用RAII,那么delete你的代码中没有多少s开头,所以额外的赋值导致混乱的论点并没有说服我.
在调试时,通常很方便查看空值而不是过时的指针.
如果这仍然困扰您,请使用智能指针或参考.
当资源被释放时,我还将其他类型的资源句柄设置为无资源值(通常仅在用于封装资源的RAII包装器的析构函数中).
我参与了一项大型(900万份报表)商业产品(主要是C).有一次,我们使用宏魔法在释放内存时使指针无效.这立即暴露了很多潜伏的错误,并迅速修复.据我所知,我们从未有过双重免费的bug.
更新: Microsoft认为这是安全性的良好实践,并建议在其SDL策略中实践.显然,如果使用/ SDL选项进行编译,MSVC++ 11将自动(在许多情况下)重写已删除的指针.
小智 12
首先,关于这个和密切相关的主题存在很多现有问题,例如为什么不删除将指针设置为NULL?.
在您的代码中,问题是(使用p).例如,如果某个地方你有这样的代码:
Foo * p2 = p;
Run Code Online (Sandbox Code Playgroud)
然后将p设置为NULL可以完成很少,因为您仍然需要担心指针p2.
这并不是说将指针设置为NULL总是毫无意义的.例如,如果p是指向资源的成员变量,该资源的生命周期与包含p的类不完全相同,则将p设置为NULL可能是指示资源是否存在的有用方法.
如果之后有更多代码delete,是的.在构造函数中或在方法或函数末尾删除指针时,编号.
这个比喻的要点是在运行期间提醒程序员该对象已被删除.
更好的做法是使用自动删除目标对象的智能指针(共享或范围).
| 归档时间: |
|
| 查看次数: |
76384 次 |
| 最近记录: |