2009-02-12 39 views
5
#define SAFE_DELETE(a) if((a) != NULL) delete (a); (a) = NULL; 

OR哪个版本的safe_delete更好?

template<typename T> void safe_delete(T*& a) { 
    delete a; 
    a = NULL; 
} 

或任何其他更好的办法

+3

其仍然愚蠢,但宏安全删除应该是:#define SAFE_DELETE(a)do {delete(a); (a)= NULL; } while(0) – 2009-02-12 14:28:50

回答

5

很明显的功能,原因很简单。宏多次评估其论证。这可能有不良副作用。此外,该功能可以作用域。没有什么比这更好的:)

5

一般来说,喜欢内联函数在宏,因为宏不尊重的范围,并可以与预处理过程中的一些符号发生冲突,导致很奇怪的编译错误。

当然,有时模板和函数不会这样做,但在这里并不是这样。

此外,更好的安全删除是不必要的,因为您可以使用智能指针,因此不需要记住在客户端代码中使用此方法,而是封装它。

编辑)正如其他人所指出的,安全的,删除是不是安全,因为即使有人不忘记使用它,它仍然可能没有预期的效果。所以它实际上完全没有价值,因为正确使用safe_delete需要的不仅仅是自己设置为0。

7

删除a;

ISO C++指定,在NULL指针上删除就不会执行任何操作。从ISO 14882

引用:

 
    5.3.5 Delete [expr.delete] 

    2 [...] In either alternative, if the value of the operand of delete is the 
     null pointer the operation has no effect. [...] 

问候,博多

/编辑:我没有注意到一个= NULL;在原来的帖子中,如此新的版本:删除一个;一个= NULL;然而,设置a = NULL的问题已经被指出(错误的安全感)。

+0

关于测试NULL和性能:我知道delete可以用NULL来调用,但是if(p!= NULL)是一个快速读取操作,可以跳过函数调用和一个assignement(写入记忆)。删除if没有错,但初级程序员读取它和性能如何? – 2016-02-10 15:51:25

+0

真的,另一方面:测试NULL是一个条件跳转。如果以某种方式编写代码,通常不会释放NULL指针,那么您只需复制该条件跳转,因为您自己执行该操作,然后调用函数,然后再次执行。所以在我的选择中,最好教导做适当的资源跟踪而不是做NULL测试。 – 2016-03-21 16:06:03

2

您无需使用delete进行无效测试,它相当于无操作。 (a) = NULL让我抬起眉毛。第二种选择更好。

但是,如果您有选择,您应该使用智能指针,如std::auto_ptrtr1::shared_ptr,这些指针已经为您执行此操作。

+0

删除时,auto_ptr和shared_ptr都不会设置为NULL。 QPointer是我知道的唯一一个这样做的课程。 – 2009-03-20 16:35:07

19

我不会说,因为两者都会给你一种虚假的安全感。例如,假设您有一个函数:

void Func(SomePtr * p) { 
    // stuff 
    SafeDelete(p); 
} 

您将p设置为NULL,但函数外部的副本不受影响。

但是,如果您必须执行此操作,请使用模板 - 宏将始终有可能对其他名称进行拼凑。

+0

好吧,一个疯狂的家伙正在潜伏着。上一个。这个答案是正确的... – gimpf 2009-02-12 11:44:23

+3

+1删除它后将指针设置为NULL很少有意义。 – 2009-02-12 14:32:33

2

我觉得

#define SAFE_DELETE(pPtr) { delete pPtr; pPtr = NULL }更好

  1. 其确定调用删除如果PPTR为NULL。所以如果检查不是必需的。
  2. 如果您调用SAFE_DELETE(ptr + i),将导致编译错误。
  3. 模板定义将为每种数据类型创建函数的多个实例。在我看来,在这种情况下,这些多重定义不会增加任何价值。
  4. 此外,使用模板函数定义,您有函数调用的开销。
0

正如前面提到的那样,第二个是更好的一个,而不是一个有潜在副作用的宏,没有对NULL的不需要的检查(尽管我怀疑你是这样做的一种类型检查)等,但都不是很有希望的安全。如果您确实使用了类似tr1 :: smart_ptr的内容,请确保您阅读了他们的文档,并确保它具有适合您的任务的正确语义。我最近不得不寻找并清理了一个巨大的内存泄漏,这是由于同事将smart_ptrs放入具有循环链接的数据结构:)(他应该使用weak_ptrs作为后向引用)

0

SAFE_DELETE的使用确实出现成为C程序员的方法来控制C++中内置的内存管理。我的问题是:C++是否允许这种方法使用SAFE_DELETE指针已被适当封装为私人?这个宏只能用于声明为Public的指针吗? OOP坏了!

0

我喜欢这个版本:

​​3210

删除它是毫无意义的,因为你会使用指针的唯一原因是,以允许在多个地方同时引用的对象后设置指针为null 。即使程序的一部分中的指针为0,也可能有其他的未设置为0.

此外,safe_delete宏/函数模板非常难以正确使用,因为它只有两个地方可以使用,如果有代码可能会抛出新的和删除给定的指针。

1)无论是里面的catch(...)块重新抛出异常,毗邻为不丢的路径赶上(...)块也被复制。 (也可以在每个中断旁边复制,返回,继续等等,这可能会使指针超出范围)

2)在拥有指针的对象的析构函数内部(除非新的和删除之间没有代码可以抛出)。

即使没有代码会抛出异常,当你写的代码,这可能在未来改变(所需要的是有人走过来,再添新后的第一个)。即使在例外情况下,仍然保持正确的编写代码更好。

选项1创建了很多代码重复,很容易出错,我甚至怀疑它可以称之为选项。

选项2会使safe_delete变得冗余,因为您设置为0的ptr_将超出下一行的范围。

概括 - 因为它是不是在所有安全不使用SAFE_DELETE(这是非常困难的正确使用,并导致冗余代码,即使它的使用是正确的)。使用SBRM和智能指针。