我在尝试删除我在向量中分配的内存时遇到了一些问题。即使我调用list.clear(),它也不会释放内存。
所以我在一个名为Set
的基于模板的类中有这样的代码template <class T>
class Set {
public:
// stuff
private:
int size;
std::vector<T> list;
};
在构造函数中,我为向量分配了内存。所以我调用list = new std :: vector;
为了您的兴趣,这里是我的复制构造函数和赋值运算符,我也在这里我也在为向量分配内存:
template <class T>
Set<T>::Set(const Set& aSet)
{
size = aSet.size;
list->clear();
list = new vector<T>;
for (int i = 0; i < size; ++i) {
list[i] = aSet.list[i];
}
}
template <class T>
Set<T>& Set<T>::operator=(const Set& right)
{
if (this != &right) {
list->clear();
size = right.size;
list = new vector<T>;
for (int i = 0; i < size; ++i) {
list[i] = right.list[i];
}
}
return (*this);
}
在析构函数中,我只有list.clear()来删除所有元素然后释放内存。
但问题是,当我在我的.out文件上运行valgrind时,它告诉我,我肯定丢失了一些内存,我不知道为什么它会告诉我这个。我在Stackoverflow上看到了一些问题,但我基本上已经尝试了一切。我尝试了clear()然后在向量上删除但是没有用。然后我尝试擦除(list.begin(),list.end()),但这也不起作用。
我的思维过程是我使用的是Set * aSet = new Set;在我的主类中,因为int不是一个对象,所以当我调用list.clear()时它不会被释放。这是正确的吗?我该如何正确删除内存?
感谢您的帮助。
Edit1 =将列表*更改为setList
我的新构造函数和赋值运算符:
template <class T>
Set<T>::Set(const Set& aSet)
{
size = aSet.size;
setList.clear();
setList = aSet.setList;
}
template <class T>
Set<T>& Set<T>::operator=(const Set& right)
{
if (this != &right) {
setList.clear();
size = right.size;
setList = right.setList;
}
return (*this);
}
Valgrind仍然报告说我有相同数量的内存损失。在我的析构函数中,我仍然有list.clear()
Valgrind日志:
==11398==
==11398== HEAP SUMMARY:
==11398== in use at exit: 62,969 bytes in 352 blocks
==11398== total heap usage: 540 allocs, 188 frees, 68,046 bytes allocated
==11398==
==11398== LEAK SUMMARY:
==11398== definitely lost: 8,624 bytes in 14 blocks
==11398== indirectly lost: 1,168 bytes in 5 blocks
==11398== possibly lost: 4,829 bytes in 56 blocks
==11398== still reachable: 48,348 bytes in 277 blocks
==11398== suppressed: 0 bytes in 0 blocks
==11398== Rerun with --leak-check=full to see details of leaked memory
答案 0 :(得分:4)
我的思维过程是我在我的主类中使用
Set *aSet = new Set;
,因为int不是一个对象,所以当我调用list.clear()时它没有被释放。这是正确的吗?我该如何正确删除内存?
没有。要删除正确分配的内存,您需要调用delete:
Set *aSet = new Set;
delete aSet;
然而,手动管理这样的内存很困难且容易出错。你应该更喜欢替代品。首先,你根本不应该使用动态分配。您应该只使用自动变量:
Set aSet;
// no delete required. Variable destroyed/deallocated when it goes out of scope.
如果你确实需要动态分配,你应该使用智能指针。
std::unique_ptr<Set> aSet(new aSet);
智能指针实现RAII以进行动态分配,因此您无需手动执行。
在某些罕见的情况下,您可能实际上需要手动进行动态分配,但这是一个高级主题。
std::vector<T>::clear()
不需要释放向量的内存。您可以使用C ++ 11成员函数shrink_to_fit()
,也可以使用交换技巧:
std::vector<int> list;
...
std::vector<int>(list).swap(list);
另外,你真的不应该使用指向矢量的指针。向量使用RAII为您管理动态内存。当您使用指向矢量的指针时,您不再拥有不自己手动管理资源的好处。
答案 1 :(得分:2)
在执行new list
之前,您需要执行delete list
,否则您将发现内存泄漏。在删除之前不需要clear
列表,析构函数会自动清除它。 编辑:您还需要删除Set
类析构函数中的指针。
一点偏离主题的提示,不要使用像list
这样可能被误认为是内置类型的变量名。
更多关于主题的提示是使用std::vector
作为直接成员变量而不是指针。在这种情况下,您肯定需要使用clear
。
答案 2 :(得分:1)
如果您使用的是C ++ 11,则可以使用shrink_to_fit()。据我所知,虽然这是非约束性的,但实施可能会阻止它实际收缩。