C++中new和delete在数组指针和指针数组中的调用

首先,先区分下数组指针和指针数组:

数组指针(也称行指针)

标准格式:A (*p)[num]         

(A为数据类型,num为无符号整数)

解释:因为()优先级别高,所以我们可以看出(*p)是一个一维指针,

把(*p)看作整体 ,从(*p)[num]我们可以看出它是一个一维的数组指针,

并且是A数据类型的,num表示该指针的步长, 所以p+1表示指针跳过num个元素,

在实践中,我们常拿来这样用:int (*p)[3] = new int[2][3];

所以p + 1跳过了第一行2个元素从而指向下一行的第一个元素p[1][0],故而称作行指针.


指针数组
参考格式: A *p[num];

(A为数据类型,num为无符号整数)
[ ]优先级高,先与p结合成为一个数组,再由A*说明这是一个A数据类型的指针数组,

它有n个指针类型的数组元素。

这里执行p+1是错误的,这样赋值也是错误的:p=a;

因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。

但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
    p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。


介绍完数组指针和指针数组后,我们用一个ClassA类的new分配和delete来说明使用示例:


//ClassA.h

#ifndef H_ClassA
#define H_ClassA

#include<iostream>
using namespace std;

class ClassA
{
public:
	ClassA(): m_ObjectIndex(m_ObjectNum)
	{ m_ObjectNum++;  cout << "ClassA:构造函数" << endl; };
	virtual ~ClassA(){ m_ObjectNum--; cout << "ClassA:析构函数" << endl; };
	void coutObjectIndex() const { cout << "ClassA对象索引:" << m_ObjectIndex << endl; }
	void coutObjectNum() const { cout <<"ClassA对象数量:" <<m_ObjectNum << endl; }
private:
	int m_ObjectIndex;
public:
	static int m_ObjectNum;
};
int ClassA::m_ObjectNum = 0;

#endif


//main.cpp

#include<iostream>
using namespace std;

#include "ClassA.h"

int main(char argc, char* argv[])
{
	//------------【前三组对象】----------------
	ClassA a;               //初始一个类对象
	a.coutObjectIndex();
	a.coutObjectNum();
	a.~ClassA();			//直接调用析构函数释放对象内存空间
	cout << endl;

	ClassA* p = new ClassA; //指针指向一个new分配的对象首地址
	p->coutObjectIndex();
	p->coutObjectNum();
	delete p;				//用delete释放对象堆空间
	cout << endl;

	ClassA* point = new ClassA[2]; //用new分配10个对象,并用指针指向首地址
	for (size_t i = 0; i < 2; i++)
		point[i].coutObjectIndex();
	point->coutObjectNum();
	delete[] point;				   //delete释放数组形式的对象队空间
	cout << endl;
	
	//----------------【数组指针】-------------------
	ClassA(*arrPoint)[3] = new ClassA[2][3];//用new分配2*3个对象,并用指定列数为3的数组指针指向首地址
	for (size_t i = 0; i < 2; i++)
		arrPoint[i]->coutObjectIndex();
	for (size_t i = 0; i < 2; i++)
	for (size_t j = 0; j < 3; j++)
		arrPoint[i][j].coutObjectIndex();
	arrPoint[0][0].coutObjectNum();
	delete arrPoint;						//数组指针其实是一个指针, 其指向是一片连续的堆空间,调用一次即可
	cout << endl;

	//---------------【一维指针数组】----------------
	ClassA* pointArr[3];					//构建维度为3的指针数组,并使其每一个元素指向一个new分配2维数组对象的首地址
	for (size_t i = 0; i < 3; i++)
	{
		pointArr[i] = new ClassA[2];
		for (size_t j = 0; j < 2; j++)
			pointArr[i][j].coutObjectIndex();
	}
	pointArr[0]->coutObjectNum();
	for (size_t i = 0; i < 3; i++)			//对指针数组每一个元素指针,调用 delete[]
		delete[]pointArr[i];
	cout << endl;

	//---------------【指向指针数组的二维数组】---------
	ClassA** twoDimPoint = new ClassA*[3];	//用new分配一个3维的指针数组对象,并用二维指针对象指向它的首地址
	(*twoDimPoint)->coutObjectNum();
	for (size_t i = 0; i < 3; i++)
	{
		twoDimPoint[i] = new ClassA[2];		//继续用new分配2维的对象,并用指针数组元素指向首地址
		for (size_t j = 0; j < 2; j++)
			twoDimPoint[i][j].coutObjectIndex();
	}
	twoDimPoint[0][0].coutObjectNum();
	for (size_t i = 0; i < 3; i++)		    //对一维指针数组每一个元素指针,调用 delete[]
		delete[] twoDimPoint[i];
	delete[] twoDimPoint;					//释放二维指针所分配的堆空间
	cout << endl;

	cout <<"为验证所有对象清理完毕, 输出最后剩余对象数量:"<<ClassA::m_ObjectNum<<endl;
	getchar();
	return 0;
}


main.cpp中注释说的比较清楚,相信大家能理解,这里我就不做过多说明了~

最后附上程序结果图,大家自己也可以运行看看:

【前三组对象】:


【数组指针】:


【一维指针数组】:


【指向指针数组的二维数组】:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值