【问题标题】:How to free memory allocated by new[]?如何释放 new[] 分配的内存?
【发布时间】:2020-11-09 19:54:54
【问题描述】:

我目前正在尝试创建类似矢量的容器。它使用new[] 分配的内存作为它的基础。当我需要扩展数组时会出现问题。我用new[] 分配了更大的内存块,然后将memcpy 旧内存分配到那里,delete[] 旧内存。问题是,试图在其中存储任何指针或任何包含指针的对象都会导致内存损坏。所以我需要一种方法来释放使用的内存而不破坏里面的对象

编辑:一些代码来理解问题:

template<typename T>
class myvector
{
private:
 T* _data;
 size_t _size, _capacity;
 static constexpr float multiplier = 1.5;
public:

void expand()
{
    size_t e_size = sizeof(T);
    size_t old_capacity = this->_capacity;
    this->_capacity = (unsigned long)(float(this->_capacity) * myvector::multiplier);
    T *tmp = new T[this->_capacity];
    memcpy(tmp, this->_data, e_size * (old_capacity));
    // this will destroy all the objects inside the container
    // which will result in destruction of any allocated memory
    delete[] this->_data; 
    // so now we have an array of invalid pointers. fun time
    this->_data = tmp;
}
}

【问题讨论】:

  • 我认为您的问题的标题有点误导,因为您已经知道如何使用 delete[] 并且它会破坏数组的内容。也许提供一些代码来说明问题,但我认为问题在于你如何复制内存。您不应该复制,而是在调整大小时移动构建对象。
  • 也许可以分享一些代码,因为这将有助于理解你的工作
  • "然后将旧内存 memcpy 到那里" - 这不适用于非 POD C++ 类型,因为它不会正确调用构造函数/析构函数。
  • memcpy 只能与trivially-copyable objects 一起使用。它不适用于具有用户定义的析构函数(或构造函数,或赋值运算符)的对象。
  • “所以我需要一种方法来释放内存而不破坏内部对象”不,你不需要,你只需要修复对象从旧存储移动到新存储的错误方式。经典的 XY 问题

标签: c++ c++11 memory-management heap-memory


【解决方案1】:

如何释放new[]分配的内存?

使用delete[]。这必须在指针值丢失之前完成,并且必须在最后一次使用指针值之后完成。它必须只做一次。除了数组new返回的指针之外,不得对任何其他指针执行此操作。

问题是,试图在其中存储任何指针或任何包含指针的对象都会导致内存损坏。

那么你如何使用这些对象就有一个错误。在模板中存储此类对象本身应该不是问题。

所以我需要一种方法来释放使用的内存而不破坏里面的对象

这根本不可能。一个对象没有存储就不能存在(除了这里不适用的特殊情况)。

delete[] this->_data; 
// so now we have an array of invalid pointers. fun time

为什么会有一个无效指针数组?数组中的指针是否指向this-&gt;_data

确实,您的数据结构中的元素没有稳定的地址。扩展将使对元素的任何引用无效。如果你需要这样的稳定​​性,那么你必须使用基于节点的数据结构,例如链表。


您的模板确实有一个限制,即它仅适用于可复制的类。也许你忽略了这个限制。摆脱这个限制很容易:只需使用std::copy(或者可能是&lt;algorithm&gt; 中的std::move,取决于您需要的异常安全保证)而不是std::memcpy

【讨论】:

    猜你喜欢
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多