我是不是应该检查并释放 VLA 类的分配运算符 (operator=) 中的指针
Posted
技术标签:
【中文标题】我是不是应该检查并释放 VLA 类的分配运算符 (operator=) 中的指针【英文标题】:Should I check and free pointer in VLA class' assign operator (operator=)我是否应该检查并释放 VLA 类的分配运算符 (operator=) 中的指针 【发布时间】:2021-09-29 21:31:26 【问题描述】:假设我们有一个简单的变长数组类,如下所示:
struct VLA
double* d=nullptr;
int dim;
让我想知道的是,在 operator=
中,我应该在 malloc/new 一个新数组之前检查(如果不是 nullptr
,则可能是免费/删除)d
?由于赋值不同于复制构造函数,它最初也可能携带一个数组。
如下例:
operator=(VLA &other)
double *tmp=new double[dim];
memcpy(tmp, other.d, sizeof(double)*other.dim);
delete[]d;
d=tmp;
dim=other.dim;
delete[]d
是必需的吗?
【问题讨论】:
VLA 指的是 C 中可用的一些特定结构。free 和 malloc 标记在这里也没有那么相关 这能回答你的问题吗? ***.com/questions/4172722/what-is-the-rule-of-three。好吧,我想不是直接的,但你需要更多delete
才能拥有一个不会被严重破坏的课程
也许你已经拥有了更多的特殊成员函数。您应该将它们包括在问题中,因为它们密切相关。
在重新分配对象时,您有责任释放旧内存以防止泄漏。 delete
将安全地处理空指针。不需要断言new
不为空,如果不能分配就会抛出异常。如果您希望 new
在分配失败时返回 null,请使用 new(::std::nothrow) double[]
。
例如,如果没有适当的构造函数,delete
可能会在 d
未初始化的情况下调用。
【参考方案1】:
在
operator=
内,我应该检查(如果不是nullptr
,则可能是免费/删除)d
在 malloc/new 一个新数组之前?
delete[]d
是必需的吗?
如果你打算用new[]
分配一个新数组,那么是的,你需要用delete[]
释放旧数组,否则会泄露。是否在分配新数组之前或之后执行此操作取决于您,但我会在之后执行,以防分配新数组失败。
请注意,如果新的dim
与旧的dim
的值相同,则可以跳过new[]
/delete[]
,并使用copy-swap idiom当你分配一个新数组时:
VLA(const VLA &other)
d = new double[other.dim];
memcpy(d, other.d, sizeof(double) * other.dim);
dim = other.dim;
VLA& operator=(const VLA &other)
if (this != &other)
if (dim == other.dim)
memcpy(d, other.d, sizeof(double) * other.dim);
else
VLA temp(other);
std::swap(d, temp.d);
std::swap(dim, temp.dim);
return *this;
不过,您确实应该完全手动使用std::vector
而不是new[]
/delete[]
。让std::vector
为你处理数组:
#include <vector>
struct VLA
std::vector<double> d;
int dim() const return d.size();
// compiler-generated copy constructor will "do the right thing"...
// compiler-generated operator=() will "do the right thing"...
;
【讨论】:
以上是关于我是不是应该检查并释放 VLA 类的分配运算符 (operator=) 中的指针的主要内容,如果未能解决你的问题,请参考以下文章