c++ 动态数组

动态数组


相关数组知识连接
数组详解
多维数组


在之前的文章中,讲解了数组的相关知识,那一种数组(数组相关连接:https://blog.csdn.net/m0_62870588/article/details/123787052)又称是静态数组,因为它的大小从头到尾是固定的。在这里将会讲解动态数组的相关知识。动态数组,严格意义上讲并不是数组,程序会使用指针来承载malloc( )或者new操作符动态分配的内存空间,然后在需要更新数组大小或者释放空间的时候使用free () 或者delete。


使用malloc()和free()动态分配内存

malloc()函数可以在一个叫堆(Heap)的内存空间中分配指定字节数的内存。与作用域中在栈(Stack)中分配内存的局部变量不同,堆中的内存一旦分配,就不会自动释放,直到数据调用free()函数.

使用malloc()

#include<iostream>
using namespace std;

//使用malloc()

int main()
{
    
    
	int *arr = (int*)malloc(5*sizeof(int)) ;
	int *ptr = arr;
	for ( int i = 0;i < 5; i++ )
	{
    
    
		*ptr = i;
		cout << *ptr << " ";
		ptr++; //也可以直接写成 cout << *(ptr++)<<" ";
	}
	cout << endl;
	free(arr);
	arr = NULL;
	return 0 ;
}

运行结果
展示了malloc()和free()的应用。
在这里插入图片描述
示例中,先使用malloc()分配了大小为“ 5 * sizeof(int)”字节的内存。malloc()的分配单位是字节,所以要用sizeof操作符获取整形int的字节数。此外,由于malloc()返回 void * 指针,因此也要将返回值转换为需要的指针类型;分配完内存之后我们就用另一个指针来遍历这个动态的数组,最后需要记得用free()函数释放内存。

对于动态数组来说,因为内存不会自动释放,所以如果遗漏free(),就会发生内存泄漏(Menory Leak),也就是说已分配的内存会一直被占用,别的程序就不能使用这一块内存了。

举个例子说明一下这个概念,可以用现实生活中更衣室的柜子来类比:更衣室的柜子在出租之后就会被上锁,顾客在使用一段时间后,把东西拿了出来,关上柜子却忘记归还钥匙就离开了。这个情况下管理人员是没有钥匙的,尽管柜子是空的却也不能提供给另外一名顾客使用。堆中的内存也是如此,如果不释放,就算只用那块内存的程序已经终止,那块内存也是处于被占用的状态。

另一个值得注意的点是,在调用free()函数的时候我们不能使用ptr,而必须使用arr。这是因为ptr在遍历结束之后指向的是动态数组的末尾元素,如果使用free()释放 5 * sizeof(int)字节内存,就会触动到最后一个元素后面的未知的内存段。

提示: 在c++程序中,如果使用动态内存分配,一定要让free()或delete与malloc()和new 匹配,即在程序中一次内存分配一定要有相对应的一次相同大小的内存释放。释放多次相同的内存、没有释放内存以及释放内存大小不匹配都是不能接受的。

此外,在释放内存后将指针重新赋值为NULL是一个非常好的习惯。这是因为对指针用了free()之后不会改变指针的值,也就是指向的地址。在之后的程序中可能会忘记这个内存的地址已经被释放,而再次使用这个指针就会导致程序异常。这个时候如果指针是NULL,就会被许多条检查拦截(就像把指针初始化NULL一样),从而避免许多潜在问题。


使用new和delete两个操作符

malloc()和free()在C语言中就存在了,c++只是继承了他们。为了更好的只支持对象的内存管理,c++引入了new和delete两个操作符。

使用new和delete

#include<iostream>
using namespace std;

//使用new和delete

int main()
{
    
    
	int *numPtr = new int (3);
	cout << *numPtr << endl;
	delete numPtr;
	int *arr = new int [5];
	int *ptr = arr;
	for ( int i = 0; i < 5;i++)
	{
    
    
		*ptr = i ;
		cout << *ptr << " " ;
		ptr++; //也可以直接写成cout << *(Ptr++) << " " ;
	}
	cout << endl;
	delete [] arr;
	arr = NULL;
	return 0 ;
}

运行结果
在这里插入图片描述
从示例中可以看出,new和delete在总体上还是malloc()和free()类似的,由于new与类似相关,因此写法上还会更简洁一些。在例子中,使用了两组new/delete对,第一个new分配了一个初始值为3的整数(这里用到了雷子于构造函数的初始方法)这个语句也可以写成“ int * numPtr = new int ;”,这样写的话整型就只有一个未知的初值。这是因为再分配了内存却没有赋值的情况下,该内存段可能还保留着上一次分配后存储的某个值。
第一组new/delete的语法相对来说比较直观。第二个new后面跟着变量类型以及元素的个数,这样的语法类似于数组的创建,而实际上也表示分配一段能放下5个int大小的内存。这里不需要像使用malloc()那样指定一字节为单位的内存大小,这样也使得程序更具有可读性。对于delete来说,如果用new分配了数组,那么就需要在delete和指针名之间加上一对括号([])以表示释放数个指针类型大小的空间,不然只会像delete numPtr那样删除一个元素,这也是new/delete与malloc()/free()的一个重要区别。


相关数组知识连接
数组详解
多维数组


如果对您有帮助,点赞支持一下吧~

猜你喜欢

转载自blog.csdn.net/m0_62870588/article/details/123839113