【问题标题】:would memory be leaked if on allocation failed in this code?如果此代码中的分配失败,内存会泄漏吗?
【发布时间】:2021-06-18 15:52:53
【问题描述】:

所以对于我的作业,我不允许使用std::smart_ptr,但是我可以自己实现它并进行任何我想要的更改

这就是我所做的

#ifndef SMART_PTR_H_
#define SMART_PTR_H_

template<class T>
class smart_ptr {
    T* data;
public: typedef T element_type;
    explicit smart_ptr(T* ptr = NULL)
   : data(ptr) {}
    ~smart_ptr() {  delete data;    }
    T& operator*() const {  return *data; }
    smart_ptr& operator=(smart_ptr<T>&);
    };
template<class T>
smart_ptr<T>& smart_ptr<T>::operator=(smart_ptr<T>& ptr)
{
    delete this->data;
    T* new_data = new T(*ptr);
    this->data =new_data;
    return *this;
}
#endif

所以我的问题是,对于这样的代码:

template <class T>
SortedList<T>::SortedList(const SortedList<T>& list):
  data(new smart_ptr<T>[list.max_size])
 ,size(list.size)
 ,max_size(list.max_size)
 {
     for (int i = 0; i < size; i++)
     {
        data[i]=list.data[i];// use of operator= of smart_ptr
     }
 }

所以如果new 抛出std::bad_alloc 会有内存分配还是 smart_ptr 的析构函数会处理所有事情?

【问题讨论】:

  • 为什么你的“排序列表”分配智能指针的动态数组?
  • IF a new threw 你问的是两个new中的哪一个?
  • @eerorika newoperator=
  • 另外,operator= 也应该参考const
  • 除了一元 operator* 之外,您还应该定义 operator-&gt; 以便您的类真正表现为智能指针。

标签: c++ memory smart-pointers bad-alloc


【解决方案1】:

所以如果一个新抛出的 std::bad_alloc 会有内存分配

如果new 抛出,那么new 将不会分配内存。但是,构造函数有可能自己进行了分配,如果构造函数抛出,一个执行不佳的构造函数可能会泄漏这些分配。

你有一个比单纯的内存泄漏更糟糕的错误:

delete this->data;
T* new_data = new T(*ptr);

如果new 抛出,那么this-&gt;data 将留下一个无效的指针。在析构函数中,无效指针将被删除,程序的行为未定义。

这意味着我应该在 new 之后进行删除?

这样会好很多,但如果析构函数抛出,它仍然有可能发生内存泄漏。

您可能应该暂时将任一智能指针的所有权转移到第三个本地智能指针。


但问题是如果 new 抛出了所有在 for 循环中成功的 new 会发生什么?

SortedList<T>::SortedList(const SortedList<T>& list):
    data(new smart_ptr<T>[list.max_size])

new[] 数组归SortedList::data 所有。如果这是一个智能指针,那么它应该在其析构函数中得到处理。如果是裸指针,则指向的数组以及数组中的智能指针都会泄漏。

请注意,由于您分配了一个数组,因此显示的 smart_ptr::~smart_ptr 不会做正确的事情,因为它不使用 delete[]

其实SortedList::~SortedList确实会删除[]数据,够吗?

没有。如果SortedList的构造函数抛出,那么它的析构函数就不会被调用。

【讨论】:

  • 这意味着我应该在new 之后执行delete
  • 但问题是,如果 new 抛出了在 for 循环中成功的所有 new 会发生什么?析构函数会处理它们吗?
  • @raghad:通常会删除旧数据,将您的成员设置为“有效”(通常为 nullptr)状态,然后然后分配新数据。
  • 其实SortedList::~SortedList确实删除了[]数据,够吗?
  • 但是如果SortedList的构造函数抛出,那么我们就不会分配任何数据了,对吗?
猜你喜欢
  • 2012-01-18
  • 2020-01-16
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 2017-12-05
  • 2012-06-01
相关资源
最近更新 更多