问题描述
我有一个带有向量成员的类。 我有访问器来设置/获取向量的值。
typedef vector<int> vint_t;
class MyVector {
public:
MyVector(const vint_t & v) : _vint(v) {};
size_t set(const vint_t & v) {
_vint = v; // Will this leak memory in the old location of _vint?
const size_t n = v.size();
return n;
}
const vint_t & get() {
return _vint;
}
private:
vint_t _vint;
};
除了set
正确设置_vint
的内容(已通过以下代码验证,operator<<
适当地重载)之外,还会set
泄漏内存_vint
的旧位置?
vint_t v1 = { 1,4,10,2 };
MyVector mv1(v1);
cout << mv1.get() << endl;
vint_t v3 = { 8,1,2 };
mv1.set(v3);
cout << mv1.get() << endl;
解决方法
否,它不会泄漏内存,这是因为对标准容器进行了合理的编程。 在这种情况下,分配只需在“ =”的右侧调用向量的每个元素的复制构造函数,然后在“ =”的左侧将其复制到向量。 在进行这种分配之前,“ =”左侧的向量将调用所有对象的析构函数。
因此,如果发生内存泄漏是由于矢量模板的object参数上的泄漏。
,设置是否会在_vint的旧位置泄漏内存?
不。 _vint
的存储位置最初没有改变。此外,未指定std::vector
的赋值运算符来泄漏内存(任何标准容器的任何操作也没有)。
当然,如果存储在向量中的对象是某些资源的句柄,那么如果在不释放资源的情况下删除了句柄,则这些对象将泄漏。在您的示例中,您使用了任意整数值,因此它们似乎不是资源句柄。
,size_t set(const vint_t & v) {
_vint = v; // Will this leak memory in the old location of _vint?
}
除非std::vector
被严重破坏,否则这不可能泄漏内存。通常,a = b;
之后的对象a
仍然是同一对象。仅复制值。您正在呼叫未中断的std::vector::operator=
。
由于_vint
是一个对象,因此不会“更改位置”。指针也不会更改位置,但是如果您通过malloc
或new
分配额外的内存,则指针可能会导致内存泄漏。
在您的示例中,您既没有使用指针,也没有分配新的内存。如果您不分配新的内存,则不会有内存泄漏,您将仅使用必要的内存,并且在退出范围(如函数)时将考虑所有内存。这不考虑无限期的嵌套作用域,例如递归函数,但是您也不使用它们。
重点是,您正在使用对象并为其分配值。值已更改,但是没有“旧位置”。这里没有内存泄漏。
,_vint = v
这是副本分配操作,因此v
的内容已复制到_vint
,但是您不会删除或创建任何对象,因此不会发生内存泄漏。另外,请记住,内存泄漏主要是在使用指针时发生的,而实际上并非如此。
这不是问题的答案,但是我确实在此代码中看到两个危险。
第一
size_t set(const vint_t & v) {
_vint = v; // Will this leak memory in the old location of _vint?
}
该函数返回size_t
,但没有return语句。我希望编译器
对此抱怨。该函数可能应该返回void
。
const vint_t & get() {
return _vint;
}
请谨慎使用。您需要注意,MyVector
对象的生存期不短于get
返回的任何引用。例如,一个简短的人为例子:
MyVector* mvp = new MyVector(v1);
const vint_t& vref = mvp->get();
delete mvp;
// ...
std::cout << vref << '\n'; // oh dear