VS2010中的Debug_VLD显示了一些来自类成员创建/初始化/删除的内存泄漏。
my_member
是类型为double *的数据成员。在构造函数中,我有
my_member = NULL ;
然后在某些方法中,我需要为my_member
分配内存。我不能在构造函数中这样做,
因为我还不知道阵列的大小,和/或大小可能因方法的不同调用而不同。我在这个方法中做的是检查成员是否为NULL。如果是这样,我为它分配空间,如果没有,我可以对数组进行操作(使用accesor []更改其元素的值)。它看起来像
void MyClass::my_method()
{
if( my_member == NULL )
my_member = new double[n_dim] ;
for(int k = 0 ; k < n_dim ; k++ )
my_member[k] = k ;
}
并且在my_member = new double[n_dim] ;
行发生内存泄漏。
在析构函数中,我有
delete[] my_member ;
有什么不对?如何正确分配?
谢谢!
答案 0 :(得分:3)
使用std::vector<double>
是首选方法,但是如果你想拥有原始double*
并编写复制构造函数,请手动移动构造函数和operator=
,你应该做这样的事情:
#include <assert.h> // for assert
#include <algorithm> // for std::swap
class MyClass
{
//
// Raw array
//
double * m_ptr; // raw pointer
size_t m_dim; // number of items in the array
public:
// Default constructor - creates empty vector
MyClass()
: m_ptr(nullptr)
, m_dim(0)
{
}
// Copy constructor
MyClass(const MyClass& src)
: m_ptr(nullptr)
, m_dim(0)
{
// Special case of empty source
if (src.m_dim == 0)
{
assert(src.m_ptr == nullptr);
return;
}
// Allocate and deep-copy from source
m_ptr = new double[src.m_dim];
m_dim = src.m_dim;
for (size_t i = 0; i < m_dim; i++)
m_ptr[i] = src.m_ptr[i];
}
// Move constructor: steal the "guts" from src
MyClass(MyClass&& src)
{
m_ptr = src.m_ptr;
src.m_ptr = nullptr;
m_dim = src.m_dim;
src.m_dim = 0;
}
// Destructor
~MyClass()
{
delete [] m_ptr;
}
// Unified operator=
MyClass& operator=(MyClass src)
{
std::swap(m_ptr, src.m_ptr);
std::swap(m_dim, src.m_dim);
return *this;
}
};
答案 1 :(得分:2)
如果您在不调用my_member
的情况下将NULL
设置为delete[]
的代码中有任何其他位置,则为是。如果你不遵守三条规则(正确实现的复制构造函数和赋值运算符),你将遇到各种各样的麻烦。
要防止出现这种情况,请改用std::vector<double>
,您可以执行以下操作:
void MyClass::my_method()
{
my_member.resize(n_dim); // yay, learned something new here
for(int k = 0 ; k < n_dim ; k++ )
my_member[k] = k ;
}
这样,你就不会管理内存,所以不需要析构函数(除非它是virtual
,在这种情况下它可以是空的。)