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

来源:互联网 发布:淘宝卖家发布宝贝品牌 编辑:程序博客网 时间:2024/05/16 19:47

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

数组指针(也称行指针)

标准格式: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中注释说的比较清楚,相信大家能理解,这里我就不做过多说明了~

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

【前三组对象】:


【数组指针】:


【一维指针数组】:


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





0 0