初始化C++;删除后指向零的指针? 在C++中,我们使用删除> /COD>运算符来删除大部分时间的对象。p>

初始化C++;删除后指向零的指针? 在C++中,我们使用删除> /COD>运算符来删除大部分时间的对象。p>,c++,pointers,memory-management,C++,Pointers,Memory Management,delete不会使指针值为空。有什么方法可以自动实现吗 e、 g 您可以编写自己的包装函数或宏来实现这一点。 但是,在一般情况下这很难,因为您可以将右值传递给delete操作符。那么,它应该将NULL赋值给什么呢?您可以编写自己的函数来执行此操作: void deleteAndReset (void** p) { delete *p; *p = null; } 没有任何测试,我给你这个: template <typename T> void deleteAndNul

delete
不会使指针值为空。有什么方法可以自动实现吗

e、 g


您可以编写自己的包装函数或宏来实现这一点。
但是,在一般情况下这很难,因为您可以将右值传递给delete操作符。那么,它应该将NULL赋值给什么呢?

您可以编写自己的函数来执行此操作:

void deleteAndReset (void** p)
{
    delete *p;
    *p = null;
}

没有任何测试,我给你这个:

template <typename T> void deleteAndNull(const T*& pointer){
    delete pointer;
    pointer = 0;
}
模板void deleteAndNull(常量T*&指针){
删除指针;
指针=0;
}

最简单的方法是将运算符delete覆盖到

  • 擦除存储器
  • 清空指针
我的建议是仔细阅读运算符重载。
这样,您就可以保留所有当前代码,而不必将所有内容都更改为函数调用。

无论如何,这没有多大帮助,因为可能有多个指针指向已删除的对象

int* p = new int;

int* q = p;

delete p;   // how do we NULL q?

最好的办法是在p超出范围之前使用delete。或者使用标准容器,这样我们根本不需要新建/删除。

编写这样的容器很简单:

template<class T>
void safe_delete(T*& p)
{
    delete p;
    p = NULL;
}
int main()
{
    int* p = new int;
    safe_delete(p);

    double* p1 = new double;
    safe_delete(p1);

}
模板
无效安全删除(T*&p)
{
删除p;
p=零;
}
int main()
{
int*p=新的int;
安全删除(p);
double*p1=新的double;
安全删除(p1);
}

不过,请注意不要将此用于数组:)

与其他指针问题的答案相同-请使用。重新发明轮子是没有意义的。

可能是一个很好的方法,使用带有指针的自动ptr将节省您的时间。

这样做是非常糟糕的做法

他们说如果有两次删除,你的程序就不会崩溃。 唉,在删除指针指向的对象后,将指针设为NULL,这只是掩盖了问题:您的程序包含bug


我向您保证,在这种情况下,您希望程序尽早崩溃,并尽可能大声地崩溃。

您的建议有两个问题

虚假的安全感

你的建议使人产生一种虚假的安全感。当然,该标准保证,如果对空指针调用
delete
,它将不会崩溃。然而,您忘记了一个小事实:没有一个指针指向您的对象

int* p = new int(8);
int* q = p;
delete p; p = 0;
delete q; // Undefined Behavior
因此,这种做法是没有用的。因为虚假的安全感比完全没有安全感更糟糕,我实际上强烈反对它。希望人们在应用
delete
之前能三思而后行

这就引出了第二个问题

你从来不敢使用
删除

delete
应保留给智能指针或其他容器的实现者。以下各项适用:

  • 仅供专家使用
  • (专家)不要*
*对于您试图实现的目标,可能已经存在一个已调试的实现

管理内存的现有工具有很多堆:

  • 无处不在的各种智能指针:
    std::unique_ptr
    std::auto_ptr
    (取决于您的C++版本)、
    std::scoped_ptr
    std::shared_ptr
    (及其比较
    std::weak_ptr
    ,或它们的boost/tr1等价物)
  • 无处不在的各种容器:
    boost::array
    boost::scoped_array
    std::vector
    (和co)
  • 还有鲜为人知但在OO中非常有用的:
    boost::ptr_vector
    (和co)
  • 甚至还有
    boost::intrusive_ptr
    和boost intrusive Containers库或boost多索引库(带有BiMap派生)
  • 可能还有其他几个boost库,可能更专业,比如boost.Signals

对于这样一个异构的野生动物,很难想象你突然发现了一种新的使用数据的方式,它与我们所做的是如此不同,以至于你需要其他东西。如果您有,请随意发布,我们将帮助您了解如何使用这些工具来适应您的情况(或者为您提供如何创建新形式的智能指针的指导)

实际上,我不确定语法,但我打算将其作为指针的引用。我不确定,但我认为这将阻止尝试删除一些不正确的内容pointer@Nawaz:在这种情况下没关系:)两者都是等价的,在您的表单中,
t
将被推断为
Foo
,而在更简单的
t&
中,
t
将被推断为
Foo*
。只要您不忘记
&
,指针的类型不会改变。有人可能会说,您的表单更好,因为它可以帮助降低过载分辨率。。。但是这个函数是如此的专业化以至于它是一个边际效益(为什么不接受它呢!)实际上:
T const*&pointer
。想想
xconst*pX=newx(1,2,3)。。。;deleteAndNull(pX)!抱歉,我无法理解您的陈述您可以将右值传递给删除运算符,您能详细说明一下吗?如何将右值传递给
delete
?实际上,右值问题可以在C++0x中使用右值引用解决。。。使用右值时,您肯定不需要将其置零。您不能覆盖
delete
运算符,只能覆盖
operator delete
。为什么您认为这是一个好主意?搜索其他问题和/或谷歌搜索,你会发现这并不清楚,这实际上不会隐藏代码中的bug(double delete,第二次删除被忽略,因为指针以前设置为0)
int* p = new int(8);
int* q = p;
delete p; p = 0;
delete q; // Undefined Behavior