C++ new和delete

NEW

在C++中,new和delete运算符用于动态分配和撤销内存的运算符。

•    开始先来熟悉一下数据的3种存储方式。

1、静态区:  全局变量。

2、堆:      程序执行是分配的内存

3、栈:      函数调用,局部变量。

     new出来的内存就是分配到堆上的。程序执行完以后,堆上分配的内存不会被操作系统自动回收,所以你不delete掉的话,操作系统不回收,那块内存就成了没爹没娘的无业游民了,这个就叫作内存泄露,因此new和delete要成对出现。分配出来的内存记得自己回收掉。静态区和栈上面分配的内存操作系统会自动回收。所以不用delete了。

举个例子
int * pt ;//声明了一个pt指针,四个字节,放在栈里面的
•pt = new int;// new了一个int形的数据放在堆里面,再把这个数据的地址赋给pt。

•       这句话的意思是你先声明了一个pt指针,四个字节,放在栈里面的,然后你new了一个int形的数据放在堆里面,再把这个数据的首地址赋给pt。delete pt;这个就是把pt指向的地址所占的内存释放掉。其实释放的就是堆上面的那个int。然后你的pt还是存在的,还在栈里面。不过你查值时,变成了null。
    看下下面的这个例子:

#include<iostream>
int main(void)
{
	using namespace std;
	int nights=1001;
	int *pt=new int;
	*pt=1001;

	cout<<"night value= ";
	cout<<nights<<":location"<<&nights<<endl;
	cout<<"int ";
	cout<<"value="<<*pt<<":Location"<<pt<<endl;
	double *pd =new double;   //allocate space for a double
	*pd=10000001.0;

	cout<<"double ";
	cout<<"value="<<*pd<<":location="<<pd<<endl;
	cout<<"location of pointer pd:"<<&pd<<endl;
	cout<<"size of pt="<<sizeof(pt);
	cout<<":size of *pt="<<sizeof(*pt)<<endl;
	cout<<"size of pd="<<sizeof(pd);
	cout<<":size of *pd="<<sizeof(*pd)<<endl;
	return 0;
}

运行结果为:
对于上面这段程序,可以这样来分析:
我们开始定义的一个int型变量占4个字节,放在栈中,然后又new了4个字节放在堆中,并把堆的数据的首地址放在变量pt中,然后通过调用指针,也放了一个1001在堆中。所以当我们调用栈中的1001时,地址是栈的地址,档我们调用堆中1001时,存放的地址是堆的地址。所以两个地址是不一样的。

    和上面的那个new一样分析,先new了一个8个字节的double型数据放在堆里面,然后在把这个数据的首地址赋给pd,程序要求输出的第三个地址就是这个数据的地址,即pd的值,要求输出的第4个地址是pd的地址,pd一般也是放在栈里,,所以这两个地址也是不一样的。

    最后输出的pd和pt的字节大小都为4 ,这个就很好理解,因为在堆里面地址的大小都是一样的,在32位系统中均为4个字节,这个程序还需要注意的一个问题就是必须声明指针所指向的类型。因为pt和pd里的值都是储存的首地址,并没有指出地址的长度,*pd是8个字节的double值,*pt是4个字节的int值,打印*pd时,cout知道要读取多少字节以及如何解释它们。

DELETE
   一般使用delete来释放指定指针所指向的内存空间
语法:
delete 指针变量; 
举例:
<span style="font-family:FangSong_GB2312;">int* p;
p = new int;
 
*p = 100;
cout << *p << endl;
 
delete p;</span>

    注意,当一个指针接受delete操作后,它就又成了一个“指向不明”的指针。尽管我们可以猜测它还是指向“原来的房子”,然而,事实上,那座“房子”已经被delete “拆迁”掉了。这将会释放p的内存,但是不会删除p本身,我们可以将p重新分配内存块。

     new [] delete []

    假如要编写一个程序,它是否使用数组,取决于运行时用户提供的信息,如果通过声明来创建数组,则在程序编译时将为它分配内存空间。不管程序最终是否使用数组,数组都在那里,它占用了内存。在编译时给数组分配内存被称为静态联编(static binding),意味着数组是在编译时加入到程序中的。但使用new时,如果程序在运行阶段需要数组,则创建它;如果不需要,则不创建。还可以在程序运行时选择数组的长度。意味着数组是在程序运行时创建时创建的,被称为动态联编(dynamic binding),这种数组叫做动态数组(dynamic array)。

new / delete 用于分配和释放单个变量的空间,而 new [] / delete[] 则用于分配连续多个变量的存间。
new [] 语法:指针变量 = new 数据类型[元素个数] 
语法实例:int* p = new int[20];

     首先,你需要迅速回想一下,如果是 int* p = new int(20); 那么该是什么作用?否则你很容易在事后把二者混了。实例中,用 new 申请分配了20个连续的整数所需的空间,即:20 * sizeof(int) = 80个字节。new int 只是分配了一个整数的内存空间,而 new int[N]却分配了N个整数的连续空间。看来,new[] 比 new “威力更猛”,所以,我们同样得记得:用 new [] 分配出空间,当不在需要时,必须及时调用 delete [] 来释放。

     delete [] 语法:delete [] 指针变量; 

//分配了可以存放1000个int的连续内存空间:
int* p = new int[1000];   
//然后使用这些空间:
…… 
//最后不需要了,及时释放:
delete [] p;
使用动态数组
#include<iostream>
int main()
{
	using namespace std;
	double * p3= new double[3];
	p3[0]=0.2;
	p3[1]=0.5;
	p3[2]=0.8;
	cout<<"p3[1] is"<<p3[1]<<".\n";
	p3=p3+1;
	cout<<"Now p3[0] is"<<p3[0]<<" and";
	cout<<"p3[1] is"<<p3[1]<<".\n";
	p3=p3-1;
	delete [] p3;
	return 0;
}
程序输出:p3[1] is 0.5.
  Now p3[0] is 0.5 and p3[1] is 0.8.
从中可知,对于指针数组,第一个元素可以使用p3[0]表示,第二个元素可以使用p3[1]表示,第三个元素可以使用p3[2]表示,这样使用指针来访问动态数组就非常简单了。另外p3=p3+1,表示的是p3[0]现在指向数组第二个元素,最后只有将它减一后指针才能指向原来的值,给delete[]提供正确的地址。

总结
不要使用delete来释放不是new分配的内存。
不要使用delete释放同一个内存两次。
如果使用new[]为数组分配内存,则应使用delete[]来释放。
如果使用new[]为一个实体分配内存,则应使用delete(没有方括号)来释放。
对空指针应用delete最安全。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值