【问题标题】:What happens to an address after delete operator has been applied to it in C++?在 C++ 中将删除运算符应用于地址后,地址会发生什么?
【发布时间】:2011-02-14 09:17:13
【问题描述】:

如果我delete一个指针例如如下:

delete myPointer;

然后,没有0分配给指针,如下所示:

myPointer = 0; //skipped this

myPointer 会指向另一个内存地址吗?

【问题讨论】:

  • @user588855:将0 分配给deleted 指针是一个有争议的主题,具体取决于具体情况,因为它可能会隐藏流/内存处理中的结构性错误。更好地使用智能指针/容器,根本不必调用delete

标签: c++ pointers delete-operator


【解决方案1】:

不,在大多数实现中,它将存储与以前相同的地址 - delete 通常不会更改地址,除非您分配新的地址值,否则它会保持不变。不过this is not always guaranteed.

不要忘记,doing anything except assigning a null pointer or another valid pointer 指向已经存在的 deleted 指针是未定义的行为 - 您的程序可能会崩溃或行为不端。

【讨论】:

    【解决方案2】:

    myPointer 将指向相同的内存地址。但是,使用该地址处的内存对您来说是无效的,因为 delete 会将其返回给运行时/操作系统,并且操作系统可能已经分配了该内存以供其他东西使用。

    【讨论】:

    • 那么,我可以将 deleted 指针与它指向(分配)的相同地址一起使用吗?是否立即,一旦指针被删除,它会被返回给操作系统,例如或其他什么?
    • @user588855: 也许它已经返回到操作系统,也许没有,也许其他一些代码(在另一个线程上)请求内存并在该地址获取内存。无论发生什么,都可能会给你带来很多痛苦——不要那样做,正确使用指针和动态内存分配。
    • 指针永远不会返回给操作系统。相反,指针指向的内存块被返回给操作系统。你不删除指针,你删除了指针指向的内存
    【解决方案3】:

    当然,不。 delete 操作不会改变指针本身 - 它释放由该指针寻址的内存。

    【讨论】:

    【解决方案4】:

    这个问题很重要!我已经看到 Visual Studio 2017 在“删除”之后更改了指针值。它引起了一个问题,因为我使用了内存跟踪工具。该工具在每个运算符“new”之后收集指针,并在“delete”之后检查它们。伪代码:

    Data* New(const size_t count)
    {
        Data* const ptr(new Data[count]);
        #ifdef TEST_MODE
        MemoryDebug.CollectPointer(ptr);
        #endif
        return ptr;
    }
    
    void Delete(Data* const ptr)
    {
        delete[] ptr;
        #ifdef TEST_MODE
        MemoryDebug.CheckPointer(ptr);
        #endif
    }
    

    此代码在 Visual Studio 2008 上运行良好,但在 Visual Studio 2017 上失败,因此我更改了第二个函数中的操作顺序。

    但是问题很好,问题存在。经验丰富的工程师应该意识到这一点。

    【讨论】:

      【解决方案5】:

      并非总是如此,但它可以改变。在设计哈希表时,我发现在对 1000 个对象进行了大约 30 次无错误测试后,地址发生了变化。它完全在删除操作后发生了变化。解决方案:使用 T_ *const 存储将要删除的对象的侧地址,其中 T_ 是指针类型和 const 限定符以确保地址不会改变。

      【讨论】:

      • 我不确定您所说的“无错误”是什么意思。你是说你在访问无效内存时没有出错吗?或者访问的操作释放了内存,这是无效的,但没有根据测试标记无效结果?或者您可能是说您将所有权从桌子转移给了客户?答案尚不清楚。此外,更可取的是智能指针(如先前的 cmets 中所述)。当智能指针不可用(直接 C?)时,可以提出一个案例 - 但您的答案需要澄清。谢谢。
      猜你喜欢
      • 2011-05-31
      • 2022-01-23
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      相关资源
      最近更新 更多