新学C++的小菜鸟请各位大大看看 重载操作符=这里为什么会造成了内存泄露

C++语言 码拜 8年前 (2016-04-06) 1200次浏览
#include<iostream>
#include<string>
using namespace std;
class CDArray
{
private:
double *m_pData; // 存放数组的动态内存指针
int m_nSize; // 数组的元素个数
int m_space; //数组的内存空间大小
private:
void Init(); // 初始化
void Free(); // 释放动态内存
inline int InvalidateIndex(int nIndex); // 判断下标的合法性(数组下标)
public:
CDArray(); // 缺省构造函数
CDArray(int nSize, double dValue ); // 其他构造函数,设置一定数组大小,并设置全部元素为0;当然还可以定义其他不同参数的构造函数,以方便用户使用
CDArray(const CDArray& arr); // 拷贝构造函数(最好为全部包含动态分配成员的类都提供拷贝构造函数)
~CDArray(); // 析构函数
void Print(); // 输出显示全部数组元素的值
int GetSize(); // 获取数组大小(元素个数)
void SetSize(int nSize); // 重新设置数组的大小。注:若nSize小于原数组大小,可截断取前nSize个元素作为新数组的元素;若nSize大于原数组大小,新增的元素的值设置缺省值0即可
double GetAt(int nIndex); // 获取某个元素
double  operator[] (int nIndex) const;  // 重载[]操作符,以便像传统数组那样通过a[k]来获取元素值
void SetAt(int nIndex, double dValue); // 设置某个元素的值
void PushBack(double dValue); // 追加一个新的元素到数组末尾
void DeleteAt(int nIndex); // 从数组中删除一个元素
void InsertAt(int nIndex, double dValue); // 插入一个新的元素到数组中
CDArray  &CDArray::operator = (const CDArray& array);   // 重载赋值操作符号”=”
};
void CDArray::Init()// 初始化
{
m_space = 1;
m_nSize = 0;
m_pData = new double[m_space];
}
void CDArray::Free()// 释放动态内存
{
delete []m_pData;
}
int CDArray::InvalidateIndex(int nIndex)
{
if(nIndex >= 0 && nIndex <m_nSize)
return 0; //表示下标合法
else
return 1;//下标异常
}
CDArray::CDArray()
{
Init();
}
CDArray::CDArray(int nSize, double dValue )
{
dValue = 0;
if(nSize == 0)
{
Init();
}
else
{
m_nSize = nSize;
m_space = nSize * 2;
for(int i = 0 ; i < nSize ; ++i)
{
m_pData[i] = dValue;
}
}
}
CDArray::CDArray( const CDArray & arr)
{
m_nSize = arr.m_nSize; //复制常规成员
m_space = arr.m_space;
m_pData = new double[m_space];
std::memcpy( m_pData , arr.m_pData , (m_space * sizeof(double)));
}
CDArray::~CDArray()
{
CDArray::Free();
}
void CDArray::Print()
{
if(m_nSize == 0)
{
std::cout<<“Error : The array is empty,so it can”t be printed.”<<endl;
exit(0);
}
else
{
for( int i = 0 ; i < m_nSize ; i++ )
{
std::cout<<m_pData[i]<<” “;
}
std::cout<<endl;
}
}
int CDArray::GetSize()
{
return m_nSize;
}
void CDArray::SetSize(int nSize) //题中返回值为INT 个人认为返回值为VOID。
{
if( nSize < m_nSize) //截断
{
for(int i = m_space ; i < m_nSize ; i ++)
{
m_pData[i] = 0;
}
}
if( nSize > m_nSize && nSize <= m_space)//设置数组的大小未大于内存空间,仅需在后添0即可
{
for(int i = m_nSize ; i < nSize ; i++)
{
m_pData[i] = 0;
}
}
if( nSize > m_space) //大于内存空间,需要重新分配内存空间
{
m_space = nSize * 2; //重新分配内存空间大小
double *temp = new double[m_space];//临时转存数组
std::memcpy( temp , m_pData , (m_nSize * sizeof(double)) );//拷贝数组
for(int  i = m_nSize ; i < nSize ; i++)
{
temp[i] = 0;
}
delete []m_pData;
m_pData = temp;
}
m_nSize = nSize;
}
double CDArray::GetAt(int nIndex)
{
if(InvalidateIndex(nIndex))//判断下标能否合法
{
std::cout<<“The index is invalid.”<<endl;
exit(0);
}
return m_pData[nIndex];
}
double CDArray::operator[](int nIndex) const
{
if(nIndex < 0 || nIndex >= m_nSize)//判断下标能否合法
{
std::cout<<“The index is invalid.”<<endl;
exit(0);
}
return m_pData[nIndex];
}
void CDArray::SetAt(int nIndex, double dValue) //重新设置数组内元素的值,无需返回值
{
if(InvalidateIndex(nIndex))//判断下标能否合法
{
std::cout<<“The index is invalid.”<<endl;
exit(0);
}
else
{
m_pData[nIndex] = dValue;
}
}
void CDArray::PushBack(double dValue)//重新设置数组内元素的值,无需返回值
{
if(m_nSize < m_space)
{
m_pData[m_nSize] = dValue ;
//m_nSize++;//数组大小加1
}
else
{
//m_nSize++;
m_space = (m_nSize + 1) * 2; //重新分配内存空间大小
double *temp = new double[m_space];//临时转存数组
std::memcpy( temp , m_pData , (m_nSize * sizeof(double)) );//拷贝数组
delete []m_pData;
m_pData = temp;
m_pData[m_nSize] = dValue ;//数组大小加1
}
m_nSize++;//数组大小加1
}
void CDArray::DeleteAt(int nIndex)//重新设置数组内元素的值,无需返回值
{
if(InvalidateIndex(nIndex))//判断下标能否合法
{
std::cout<<“The index is invalid.”<<endl;
exit(0);
}
else
{
for(int i = nIndex ; i <m_nSize ; i++) //修改后续数组
{
m_pData[i] = m_pData[i+1];
}
m_pData[m_nSize – 1] = 0 ;
m_nSize–;
}
}
void CDArray::InsertAt(int nIndex, double dValue)
{
if(nIndex < 0 || nIndex > m_nSize)//判断下标能否合法(一开始写的程序当中判断式为nIndex >= m_nSize,这样测试代码中的类a中无法插入元素)
{
std::cout<<“The index is invalid.”<<endl;
exit(0);
}
if( m_nSize < m_space)//数组未超过内存空间 直接插入
{
for(int i = (m_nSize – 1) ; i >= nIndex ; i–)
{
m_pData[ i + 1] = m_pData[i];
}
m_pData[nIndex] = dValue;
//m_nSize++;
}
else
{
//m_nSize++;
m_space = m_nSize * 2; //重新分配内存空间大小
double *temp = new double[m_space];//临时转存数组
std::memcpy( temp , m_pData , (m_nSize * sizeof(double)) );//拷贝数组
delete []m_pData;
m_pData = temp;
for(int i = (m_nSize – 1) ; i >= nIndex ; i–)
{
m_pData[ i + 1] = m_pData[ i ];
}
m_pData[nIndex] = dValue;
}
m_nSize++;//数组大小加1
}
CDArray  &CDArray::operator = (const CDArray& array)
{
//m_pData = array.m_pData;
m_nSize = array.m_nSize;
m_space = array.m_space;
for( int i = 0 ; i < m_nSize ; i++)
{
m_pData[i] = array.m_pData[i];
}
return *this;
}
void main()
{
CDArray a;
a.InsertAt( 0 , 2.1);
a.Print();
a.PushBack(3.0);
a.PushBack(3.1);
a.PushBack(3.2);
a.Print();
a.DeleteAt(0);
a.Print();
a.InsertAt(0,4.1);
a.Print();
CDArray acopy = a;//拷贝函数
acopy.Print();
CDArray acopy2 (a);
acopy2.Print();
CDArray acopy3;
acopy3 = a;
acopy3.Print();
}
解决方案

40

if (&array != this)
{
    this->~CDArray();
    new (this) CDArray(array);
}
return *this;

取巧一点就是这样,务实一点就把析构函数和拷贝构造函数抄一遍


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明新学C++的小菜鸟请各位大大看看 重载操作符=这里为什么会造成了内存泄露
喜欢 (0)
[1034331897@qq.com]
分享 (0)