C++动态数组的分配

版权声明:【fishing-pan:https://blog.csdn.net/u013921430转载请注明出处】 https://blog.csdn.net/u013921430/article/details/79601429

【fishing-pan:https://blog.csdn.net/u013921430转载请注明出处】

  1. 前言
    上周,写了一篇《细说C++中的数组之静态数组》,今天讲述一下动态数组。

    数组是一种顺序存储的数据结构,在定义数组时,首先要确定数组的大小。静态数组在编译时就需要确定数组的大小,所以,为了防止内存溢出,我们尽量将数组定义的大一些,但是这样太过浪费内存。

    动态数组则不同,它不需要在编译时就确定大小,它的大小在程序运行过程中确定,所以可以根据程序需要而灵活的分配数组的大小,相比静态数组,它更“灵活”、“自由”。但是动态数组需要进行显式的内存释放。

  2. 动态数组内存分配
    动态数组进行内存分配的格式为new T[size],size可以不是常量表达式;如下面的例子所示。

int size = 10; //此处的size不是常量表达式。

int* Dynamic_Arr2 = new int[size]; //未初始化
可以看出,虽然我们分配了一个动态数组,其实返回的是一个T类型的指针,指针指向的是数组的第一个元素,从这个角度来说,动态数组更像是指针。也是由于这种性质,导致了动态数组中size可以取0,即返回一个空指针,即分配一个空动态数组是合法的。同样的道理,返回的是一个指针,那么就不能使用begin或者end迭代器进行遍历。

  1. 动态数组初始化
    上面的例子中,Dynamic_Arr2并未进行初始化,若想进行默认初始化,需要在数组后面加上一个小括号。

int* Dynamic_Arr3 = new intsize; //默认的初始化;
此时数组中的十个值都为0;

 也可以利用花括弧进行显式的初始化,例子如下;

string* Dynamic_Arr4 = new string[size]{“aa”, “bb”,“cc”, “dd”, string(2, ‘e’) }; //显式的初始化
注意:显式地初始化时,元素数目不能大于数组大小。其次,显式初始化可能会因为编译器版本原因报错,笔者在VS2013与VS2017下进行测试,VS2013下在释放内存时出现内存错误。

  1. 动态数组释放
    释放动态数组时,使用delete[ ] arr_name;即在数组名前加上一个中括弧;例如

delete [ ] Dynamic_Arr4;
释放一个动态数组时,或者说是指向数组的指针时,空括号是必须的。它告诉编译器,指针指向一个数组的第一个元素。

 delete释放数组是逆序进行的,最后一个元素被最先释放,第一个元素最后一个被释放。

  使用动态数组时,一定要记得显式的释放内存,否则很容易出错,比如在一个大的工程中,某一个for循环中或者某个函数中申请了内存却没释放,当函数不断地被调用,这些申请过的内存会一直堆积,直到最后退出程序。这很可能造成非常大的麻烦。

比如下面两个函数;

void not_delete_fun()
{
int *arr_test = new int[10];

cout << arr_test << endl;

//delete[] arr_test;

}
void delete_fun()
{
int *arr_test = new int[10];

cout << arr_test << endl;

delete[] arr_test;

}
分别调用和释放两个函数三次,看看结果;

  可以看出,释放过内存后,每次数组申请的内存是一致的,未释放内存的函数,每次申请数组的内存是不一样的,说明这些数组申请的内存并不会自动释放,而是会随着程序运行一致累积。
  1. 多维动态数组的内存申请
    //-----------------多维数组内存申请-------------------//
    int MAX_NUM = 10;
    int COL_NUM = 5, ROW_NUM = 3;
    double ***Arr3D = new double **[MAX_NUM];

    for (int i = 0; i < MAX_NUM; i++)
    {
    Arr3D[i] = new double *[ROW_NUM];

     for (int j = 0; j < ROW_NUM; j++)
     {
     	Arr3D[i][j] = new double[COL_NUM];
     }
    

    }

    从上面可以看出,多维数组的申请与多维vector的定义类似,是一层一层的申请内存的,返回的是指向指针数组的指针。
    
    
    
    先依次声明维度的大小,然后从最低维度开始申请内存。先申请ROW_NUM个大小为COL_NUM的数组,将指向这些数组的首地址的指针传递到大小为ROW_NUM的数组中,构成一个新的数组,以此类推,完成内存申请。
    

    上面的例子中得到的是一个10层,3行,5列的数组。

  2. 多维动态数组内存释放
    多维动态数组的释放是从最低维度开始的。先释放掉最低维度的一维数组,然后依次释放内存,直到释放掉最高维度。就跟一层一层的拆房子一样。

for (int i = 0; i < MAX_NUM; i++)
{
for (int j = 0; j < ROW_NUM; j++)
{
delete[] Arr3D[i][j];
}
delete[] Arr3D[i];
}
delete[] Arr3D;

  1. 最后
    C++中还提供了allocator类进行动态数组的内存申请,大家可以根据需要自己学习。在此不做讲解。最后附上所有代码,需要的小伙伴可以自行使用。

#include
#include
using namespace std;

void not_delete_fun()
{
int *arr_test = new int[10];

cout << arr_test << endl;

//delete[] arr_test;

}
void delete_fun()
{
int *arr_test = new int[10];

cout << arr_test << endl;

delete[] arr_test;

}

int main()
{
int *Dynamic_Arr1 = NULL;
Dynamic_Arr1 = new int[10];

int size = 10;
int *Dynamic_Arr2 = new int[size];       //未初始化;

int *Dynamic_Arr3 = new int[size]{10,9,2,8,3,6,4};     //默认的初始化;

string a = "ee";
string *Dynamic_Arr4 = new string[size]{"aa", "bb", "cc", "dd", string(1, 'e'), "aa", "bb", "cc", "dd", string(2, 'e')};      //显式的初始化
//string *Dynamic_Arr4 = new string[size];
//cout << Dynamic_Arr4[4] << endl;


cout << "未释放内存的数组位置" << endl;
for (int i = 0; i < 3; i++)
{
	
	not_delete_fun();
	
}
cout << "释放过内存的数组位置" << endl;
for (int i = 0; i < 3; i++)
{		
	delete_fun();
}

//-----------------多维数组内存申请-------------------//
int MAX_NUM = 10;
int COL_NUM = 5, ROW_NUM = 3;
double ***Arr3D = new double **[MAX_NUM];

for (int i = 0; i < MAX_NUM; i++)
{
	Arr3D[i] = new double *[ROW_NUM];

	for (int j = 0; j < ROW_NUM; j++)
	{
		Arr3D[i][j] = new double[COL_NUM];
	}
}
//cout << Arr3D[9][4][2] << endl;


for (int i = 0; i < MAX_NUM; i++)
{
	for (int j = 0; j < ROW_NUM; j++)
	{
		delete[] Arr3D[i][j];
	}
	delete[] Arr3D[i];
}
delete[] Arr3D;




delete[] Dynamic_Arr1;
delete[] Dynamic_Arr2;
delete[] Dynamic_Arr3;
delete[] Dynamic_Arr4;

system("pause");
return 0;
}

作者:不用先生
来源:CSDN
原文:https://blog.csdn.net/u013921430/article/details/79601429
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值