这段代码是否存在内存泄漏问题?

3

所以我和一个朋友在争论,解决这个问题还有什么比Stack Overflow更好的途径呢?

举个简单的例子。假设其他所有函数都已经实现正确。这个复制构造函数会泄漏内存吗?

我的观点是它绝对不会。它为新对象分配了 [rhs._size] 的内存,在对象超出范围时通过析构函数释放,而为 rhs 分配的内存在其自己的析构函数中被释放。

template<typename T>
class dynarray
{
private:
    T* _data;
    std::size_t _size;

public:
    dynarray(const dynarray& rhs)
        : _data(new T[rhs._size]), _size(rhs._size)
    {
        std::copy(rhs._data, rhs._data + rhs._size, _data);
    }

    ~dynarray() { delete[] _data; }
};

1
你的朋友为什么认为它会泄漏内存?我不认为会,但由于缺少赋值运算符(只需使用向量),看起来容易受到双重释放的影响。 - ajshort
虽然问题有点菜,但是你怎么使用这个类呢?(声明、用法、目的) - rain_
1个回答

8

是的,你可以泄漏内存。

如果std::copy引发异常,就会出现内存泄漏。这可能是因为元素赋值引发了异常。所有这些都取决于Trhs的状态。

具体来说,如果对于任何非负整数n < rhs._size,以下内容引发异常,则会泄漏内存:

 *(_data + n) = *(rhs._data + n);

2
为了修复它,请使用std::unique_ptr<T[]>代替T*作为内部数组的类型。这还消除了需要用户定义析构函数的需要,并使复制赋值默认为删除而不是破坏。 - Ben Voigt
很好的观点。我已经删除了我的答案,因为我认为你的更加技术上正确。是的,T的复制构造函数可以是noexcept,也可以不是,所以这取决于情况。 - AndyG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接