【问题标题】:What happens to the values stored in memory that has been dynamically allocated after the deconstruction is called?调用解构后动态分配的内存中存储的值会发生什么?
【发布时间】:2019-06-17 15:47:59
【问题描述】:

在闲置的赋值运算符中,我正在删除我所在的类的一个动态分配的数据成员。我在上交代码时不小心留下了“删除”,但它似乎仍然工作得很好。当我调用 delete 时到底发生了什么?如果我在将 m_itemArray 分配给 Swap 函数中的 temp 之前删除它,那么 swap 函数如何仍然工作?

赋值运算符:

Set& Set::operator=(const Set& rhs)
{
    if (this != &rhs)
    {
        delete[] m_itemArray;
        Set temp(rhs);
        swap(temp);
    }
    return *this;
}

交换功能:

void Set::swap(Set& other)
{
    ItemType * temp = m_itemArray;
    m_itemArray = other.m_itemArray;
    other.m_itemArray = temp;
}

我现在认为它的工作方式是让计算机访问 m_itemArray 正在使用的内存,但我很幸运,因为此时计算机并没有编辑存储在该内存空间中的任何内容我正在访问交换功能。

【问题讨论】:

  • 简而言之?什么都没发生。为什么编译器应该让发生任何事情发生(就效率而言)?
  • 如果我之前删除了 m_itemArray,如何设置 temp = m_itemArray?
  • 这是未定义的行为。
  • 加起来:问undefined behavior的行为是徒劳的,不能肯定回答,因为行为是undefined i>.
  • 关于运气的说明。这不是。幸运的是,当程序使错误变得非常明显并迫使您在其他潜伏的错误出现在现场并导致某人死亡之前修复它。

标签: c++ memory-management dynamic-memory-allocation assignment-operator


【解决方案1】:

您的假设几乎可以肯定是正确的。除了在非常高安全性的系统中或使用调试工具时,没有理由重写已释放的内存(删除操作会发生这种情况)。

实际上,即使释放本身也可能不会立即发生,而是在更方便的时间执行(此操作可能会变得越来越复杂,并成为所谓的垃圾收集器,这反过来可以渲染不需要使用显式发布 - 但主题变得复杂)。

因此,直到那一刻,内存仍然可以访问并且可以使用。即使在之后,该值也有可能未被重用和覆盖,并且仍然可行(这可能有助于隐藏实际上是危险的错误)。当然,你没有任何保证,试图访问释放的内存可能会导致各种麻烦。

要捕获此类错误,在某些系统中,您可以将可执行文件与不同的内存管理器或库链接,这些内存管理器或库将在实际释放之前用随机值或指示值覆盖即将释放的内存。对于没有真正硬件保护支持的旧系统,例如MS-DOS,这是唯一可能的检查,并且在很长一段时间内它仍然是一种流行的选择(例如,我记得 electricfence)。

【讨论】:

  • 谢谢!因此,在像我这样的小程序中,我很可能不会遇到问题,但是在我的赋值运算符中去掉删除行仍然要干净得多?
  • @AshBal “谢谢!所以在像我这样的小程序中,我很可能不会遇到问题” 这是一个严重的问题,你不能依赖你的观察。未定义的行为是未定义的行为,句号!而是正确地做。
  • c++ 程序通常不使用垃圾收集器(在那些使用它的少数程序中,您不会显式调用delete,因为垃圾收集器应该为您处理)。 delete 运算符所做的(在执行适当的析构函数方法之后)是将不再使用的内存块的指针添加回堆的可用内存块列表中,以便下次程序想要分配一些内存(例如使用new 运算符),它可以交给该内存块以供重复使用(如果合适)。
【解决方案2】:

严格来说,删除什么都不算什么;它不再拥有,但直到其他东西写入它之前,值仍然存在(对于大多数分配器)。但是,尝试访问未分配的内存是未定义的行为,任何事情都可能发生。

当我调用 delete 时到底发生了什么

内存被释放回给管理器。

如果我在将 m_itemArray 分配给 Swap 函数中的 temp 之前删除它,那么 swap 函数如何仍然有效?

它只是碰巧还在那里。行为未定义。

【讨论】:

  • 谢谢!所以看起来我很幸运,当我在 Swap 中再次使用这些值时,没有任何东西写入我释放的内存中。
猜你喜欢
  • 2011-04-11
  • 1970-01-01
  • 2013-09-07
  • 2014-12-20
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多