第20节 动态分配内存

第20节 动态分配内存

1.new与delete运算符
1、new与delete运算
► 在使用数组的时候,总有一个问题困扰着我们: 
    ►数组应该有多大? 
    
    ►而如下操作是错误的: 
	int n; cin>>n; //输入n值 
	double A[n][n]; //意图由输入n值确定数组大小

► C++内存分配有两种方式:静态分配和动态分配。 
    
    ►静态分配指在编译时为程序中的数据对象分配相应的存储空间,本书前面所有例子中的变量、数组、指
    	针定义等均是静态分配方式。 
    ►由于是在编译时为数据对象分配存储空间,因此就要求在编译时空间大小必须是明确的,所以数组的长
    度必须是常量。而一旦编译完成,运行期间这个数组的长度就是固定不变的。

    ►动态分配是程序运行期间根据实际需要动态地申请或释放内存的方式,它不象数组等静态内存分配方式
    那样需要预先分配存储空间,而是根据程序的需要适时分配,且分配的大小就是程序要求的大小。因此,
    动态分配方式有如下特点: 
        ►①不需要预先分配存储空间; 
        ►②分配的空间可以根据程序的需要扩大或缩小;

► new与delete运算
    int *p1, *p2; 
    char *pz1,*pz2; 
    p1=new int; //分配一个整型空间,若成功则p1指向该空间,否则p1为NULL 
    p2=new int(10); //分配一个整型空间,且给这个整型赋初值10,即*p2为10 
    pz1=new char[80]; //分配一个字符数组(字符串)空间,即pz1为字符串指针
    pz2=new char[5][80]; //分配一个二维字符数组(字符串数组)空间,即pz1为字符串数组指针 
    delete p1; //释放p1指向的整型空间 
    delete [] pz1; //释放pz1指向的字符串空间

	►(1)new运算结果是指向分配得到的内存空间的指针,如果没有足够的内存空间可以分配,其运算结
          果是一个0值指针。 
	►(2)销毁对象后,指针p1变成没有定义,然而它仍然存放先前所指向的对象(已销毁)的地址,因此
          指针p1不再有效,称这样的指针为迷途指针。通常在delete运算之后将指针重设为0值指针,避
          免迷途指针。
	►(3)用new创建的动态对象使用完后,必须用delete销毁它。 
	►(4)delete只能删除由new创建的动态对象,否则将导致程序错误。        

在这里插入图片描述

2、动态内存的应用
►(1)静态内存管理由编译器进行,程序员只做对象定义(相当于分配),而动态内存管理按程序员人为的
      指令进行。 
►(2)动态内存分配和释放必须对应,即有分配就必须有释放,不释放内存会产生“内存泄漏”,后果是随着
      程序运行多次,可以使用的内存空间越来越少;另一方面,再次释放已经释放的内存空间,会导致程
      序出现崩溃性错误。
►(3)静态分配内存的生命期由编译器自动确定,要么是程序运行期,要么是函数执行期。动态分配内存的
      生命期由程序员决定,即从分配时开始,至释放时结束。特别地,动态分配内存的生命期允许跨多个
      函数。 
►(4)静态分配内存的对象有初始化,动态分配内存一般需要人为的指令赋初始值。 
►(5)避免释放内存后出现“迷途指针”,应及时设置为空指针。

【例20.1】动态内存举例。    
    1 #include <iostream> 
    2 using namespace std; 
    3 int *f1(int n) //分配n个整型内存,返回首地址 
    4 { 	int *p, i; 
    5 		p = new int[n]; //分配 
    6 		for (i=0; i<n; i++) p[i]=i; //赋初始值 
    7 		return p; //动态分配的指针返回是有意义的 
    8 } 
    9 void f2(int *p,int n) //输出动态内存中的n个数据 
   10 { while (n-->0) cout<<*p++<<" "; } 
   11 void f3(int *p) 
   12 { delete [] p; } //释放内存
   13 int main() 
   14 { 
   15 		int *pi; 
   16 		pi=f1(5); //分配 
   17 		f2(pi,5); //输出 
   18 		f3(pi); //释放 
   19 		return 0;
   20 }   
2.动态分配数组和字符串
3、动态分配数组
►使用动态内存,可以轻而易举地解决这样的问题:在程序运行时产生任意大小的“数组”。
►动态分配一维或多维数组的方法是由指针管理数组,二维以上数组按一维数组方式来处理,具体步骤为: 
    ►①定义指针p; 
    ►②分配数组空间,用来存储数组元素,空间大小按元素个数计算; 
    ►③按一维数组方式使用这个数组(例如输入、输出等); 
    ►若是一维数组,则元素为p[i];若是二维数组,则元素为p[i*M+j],其中M为列元素个数,以此类推。 
    ►④释放数组空间;
    
【例20.2】计算N*N二维数组的元素平均值 
    1 #include <iostream> 
    2 using namespace std; 
    3 double AVE(double *A,int N) //计算N*N二维数组元素的平均值 
    4 { 	int i,j,sum=0; 
    5 		for(i=0;i<N;i++) 
    6 			for(j=0;j<N;j++) sum=sum+*(A+i*N+j); 
    7 		return sum/(N*N); 
    8 } 
    9 int main() 
   10 { 	int i,j,n=4; cin>>n; 
   11 		double *A=new double[n*n]; //分配“数组”A[n][n] 
   12 		for (i=0;i<n;i++) 
   13 			for (j=0;j<n;j++) cin>>*(A+i*n+j); //输入数据到A[i][j] 
   14 		cout<<"detA="<<AVE(A,n)<<endl; 
   15 		delete [] A; //释放“数组” 
   16 		return 0; 
   17 }  
4、动态分配字符串
1. 动态分配字符串 
    ►实际编程中,字符串类型表示文字信息数据,其特点是字符长度不固定。通过动态分配字符串,根据
    程序的需要确定字符串的实际长度。 
    ►动态分配字符串的方法是由字符指针管理字符串,具体步骤为: 
        ►①定义字符指针; 
        ►②分配字符串空间,用来存储字符串; 
        ►③使用这个字符串(例如输入、输出等); 
        ►④释放字符串空间;
    		char *p=new char[1000]; //分配字符串空间 
			cin>>p; //输入字符串 
			cout<<p; //输出字符串 
			delete [] p; //释放字符串空间
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值