C++ 为什么';t delete是否将指针设置为NULL?

C++ 为什么';t delete是否将指针设置为NULL?,c++,memory-management,delete-operator,C++,Memory Management,Delete Operator,我一直想知道为什么删除后自动将指针设置为NULL不是标准的一部分。如果解决了这个问题,那么许多由于无效指针导致的崩溃就不会发生。但话虽如此,我仍能想到该标准限制这一点的两个原因: 性能: 附加指令可能会降低delete性能 可能是因为const指针 我想,标准公司本可以为这种特殊情况做些什么 有人知道不允许这样做的确切原因吗 因为实际上不需要删除,而且需要删除指向指针的指针,而不仅仅是指针。如果您有一个指针数组,并且您的第二个操作是删除空数组,那么在内存即将释放时,没有必要将每个值设置为null

我一直想知道为什么删除后自动将指针设置为NULL不是标准的一部分。如果解决了这个问题,那么许多由于无效指针导致的崩溃就不会发生。但话虽如此,我仍能想到该标准限制这一点的两个原因:

  • 性能:

    附加指令可能会降低
    delete
    性能

  • 可能是因为
    const
    指针

    我想,标准公司本可以为这种特殊情况做些什么


  • 有人知道不允许这样做的确切原因吗

    因为实际上不需要删除,而且需要删除指向指针的指针,而不仅仅是指针。

    如果您有一个指针数组,并且您的第二个操作是删除空数组,那么在内存即将释放时,没有必要将每个值设置为null。如果希望它为空。。写入null:)

    首先,设置为null需要内存存储变量。的确,通常在变量中有一个指针,但有时可能需要删除刚计算出的地址处的对象。如果删除“无效”,这是不可能的

    然后是表演。您可能以这样的方式编写代码,即删除完成后指针将立即超出范围。用null填充它只是浪费时间。C++是一种语言,它不需要它,那么你就不必为它付费了。
    如果您需要安全,您可以使用各种各样的智能指针,或者您可以编写自己的智能指针—更好、更智能。

    您可以使用多个指针指向该内存。如果为delete指定的指针设置为null,而其他所有指针都没有设置,则会产生错误的安全感。指针只不过是一个地址,一个数字。它也可以是带有解引用操作的int。我的观点是,您还必须扫描每一个指针,以找到那些引用您刚才删除的相同内存的指针,并将其清空。扫描该地址的所有指针并将其置零将是一种计算密集型操作,因为该语言不是为此而设计的。(尽管其他一些语言以不同的方式构造它们的引用以实现类似的目标。)

    指针可以保存在多个变量中,但将其中一个变量设置为NULL仍会在其他变量中留下无效指针。所以你并没有得到太多,你更有可能制造一种虚假的安全感

    除此之外,您还可以创建自己的函数来满足您的需求:

    template<typename T>
    void deleten(T *&ptr) {
      delete ptr;
      ptr = NULL;
    }
    
    模板
    无效删除(T*&ptr){
    删除ptr;
    ptr=NULL;
    }
    
    C++允许您定义自己的运算符new和delete,例如,它们将使用您自己的池分配器。如果这样做,那么就可以将new和delete与严格意义上不是地址而是池数组中的索引一起使用。在此上下文中,NULL(0)的值可能具有法律意义(指池中的第一项)。

    因此,让delete将其参数自动设置为NULL并不总是意味着将该值设置为无效值。无效值不一定总是空的。

    自动将指针设置为空并不能解决大多数指针使用不当的问题。唯一可以避免的崩溃是,如果您尝试删除它两次。如果在这样的指针上调用成员函数呢?它仍然会崩溃(假设它访问成员变量)。C++不限制你在空指针上调用任何函数,也不应该从性能的角度调用它。

    答案。摘录:

    C++显式允许 delete到zero out的实现 一个左值操作数,我希望 实现会做到这一点, 但这个想法似乎没有什么意义 受到实现者的欢迎

    <>但是他提出的主要问题是删除的参数不需要是LValuy。

    < P> C++的哲学是“只使用它就付费”。我想这也许能回答你的问题

    有时,您也可以拥有自己的堆来恢复已删除的内存。。或者有时指针不属于任何变量。或存储在几个变量中的指针-可能只有其中一个变量为零。

    正如您所看到的,它有许多问题和可能的问题。

    delete
    主要用于析构函数,在这种情况下,将成员设置为NULL是没有意义的。几行之后,在结束时
    }
    ,该成员不再存在。在赋值运算符中,删除之后通常会有赋值

    此外,它还将导致以下代码非法:

    T* const foo = new T;
    delete foo;
    

    还有一个原因;假设delete将其参数设置为NULL:

    int *foo = new int;
    int *bar = foo;
    delete foo;
    

    bar应该设置为NULL吗?你能概括一下吗

    我看到人们对这个问题给出了奇怪的答案

    ptr=NULL; 如此简单的语句如何导致性能延迟

    另一个答案是,我们可以有多个指针指向同一个指针 内存位置。我们当然可以。在这种情况下,一个指针上的delete操作将只使该指针为NULL(如果delete使指针为NULL),而另一个指针将为非NULL,并指向空闲的内存位置

    解决方法应该是用户删除指向同一位置的所有指针。在内部,它应该检查内存是否已经释放,而不是不释放。仅使指针为空


    Stroustrup可以设计delete以这种方式工作。他认为程序员会处理这个问题。所以他忽略了。

    是的,但这会导致相同的开销点wrt计算地址,即使这是你不经常看到的东西。当你说有时你可能想删除一个对象时,你在谈论新的位置吗