CArray::SetSize 的用法

CArray 使用不当会产生内存碎片,应先调用SetSize(),MSDN和网友都这么说,但具体怎么用还不是太清楚,先看代码:

 

// 1. 声明arr1后直接加
CArray<int> arr1;
arr1.Add( 1 );
TRACE( "1, 0x%x, ", &arr1[0] );
arr1.Add( 2 );
TRACE( "0x%x, %2i\r\n", &arr1[0], arr1.GetCount() ); // 显示第一个元素的地址变化

// 2. 声明后设置大小
CArray<int> arr2;
arr2.SetSize(2);
arr2.SetAt( 0, 1 );
TRACE( "2, 0x%x, ", &arr2[0] );
arr2.SetAt( 1, 2 );
TRACE( "0x%x, %2i\r\n", &arr2[0], arr2.GetCount() );  // 显示第一个元素的地址变化

// 3. 声明后设置预留大小
CArray<int> arr3;
arr3.SetSize( 0, 80 );
arr3.Add( 1 );
TRACE( "3, 0x%x, ", &arr3[0] );
for( int i = 0; i < 79; i++ )
	arr3.Add( 2 );
TRACE( "0x%x, %2i\r\n", &arr3[0], arr3.GetCount() ); // 显示第一个元素的地址变化

 

运行结果:

1, 0x2bcf58, 0x2bcf98,  2
2, 0x2b9e78, 0x2b9e78,  2
3, 0x2b9ec0, 0x2b9ec0, 80

从以上结果看出,第一种方法未用SetSize是错的,执行arr1.Add( 2 )时会重新给第一项分配内存,内存地址变了(0x2bcf58, 0x2bcf98),第二、三种方法正确,添加元素时,不重新分配内存,内存地址不变。

 

说明:

 

void SetSize(
   INT_PTR nNewSize,
   INT_PTR nGrowBy = -1 
);

 

nNewSize 分配数组元素,用SetAt方法初始化元素。

nGrowBy 预留一定空间,GetSize方法取不到这一部分,用Add方法加元素。

 

总结:

使用数组前先用SetSize分配空间。

如果已知数组大小,用SetSize(50)方法分配内存,再用SetAt方法初始化。

如果不确定数组大小,用SetSize(0, 100)方法预留内存,用Add方法初始化,第二个参数可以取大些,保证够用。

 

补充说明 2018/8/26

今天使用VS2017的堆分析工具,有了进一步的理解。

1. SetSize(INT_PTR nNewSize, INT_PTR nGrowBy)并不预分配内存,在第一次执行Add或InsertAt时分配nGrowBy内存,用完时再分配nGrowBy内存。

2. RemoveAll将销毁已经分配的内存,下次调用Add时再分配。如果频繁清除时请使用RemoveAt,不会重新分配内存。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[选做]下面是一个数组类CArray的定义。要求: (1)在此基础上增加print()成员函数打印数组, (2)重载“=”、“+”、“-” 运算符使之能对该数组类对象进行赋值、加减运算。 (3)写出主函数对该类进行测试。 class CArray {private: int* p_arr; int size; public: CArray(); //缺省构造函数 CArray(int* p_a,int s); //构造函数 CArray(const CArray &r_other);//复制构造函数 ~CArray();//析构函数 int operator[](int pos) const; //访问数组元素值的下标运算符重载函数 int& operator[](int pos); //设置数组元素值的下标运算符重载函数 CArray &operator=(const CArray &other)//赋值运算符“=”重载函数 CArray operator+(const CArray &other) //加运算符“+”重载函数 CArray operator-(const CArray &other) //减运算符“-”重载函数 void print() const; }; CArray:: CArray() { p_arr=NULL; size=0;} CArray:: CArray(int* p_a,int s) { if(s>0) { size=s; p_arr=new int[size]; for(int i=0;i<size;i++) p_arr[i]=p_a[i]; } Else { p_arr=NULL; size=0; } } CArray::CArray(const CArray &r_other) { size=r_other.size; if(size) { p_arr=new int[size]; for(int i=0;i<size;i++) p_arr[i]=r_other.p_arr[i]; } } CArray::~CArray() { if(p_arr) delete[] p_arr; p_arr=NULL; size=0; } int CArray::operator[](int pos) const { if(pos>=size) return p_arr[size-1]; if(pos<0) return p_arr[0]; return p_arr[pos]; } int& CArray::operator[](int pos) { if(pos>=size) return p_arr[size-1]; if(pos<0) return p_arr[0]; return p_arr[pos]; }
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值