new和delete3
想弄懂这个问题,首先你要弄清楚数据的3种存储方式。
1。静态区: 全局变量。
2。堆: 程序执行是分配的内存
3。栈: 函数调用,局部变量。
new出来的内存就是分配到堆上的。程序执行完以后,堆上分配的内存不会被操作系统自动回收,所以你不delete掉的话,操作系统不回收,那块内存就成了没爹没娘的无业有民了,这个就叫内存泄露。
我这样说你应该知道为什么书上为什么说new和delete要成对出现了吧。分配出来的内存记得自己回收掉。
静态区和栈上面分配的内存操作系统会自动回收。所以不用delete了。
另外,我觉得你好像没有搞清楚new出来了什么东西,delete掉了什么东西。我给你举例子说。
int * pt ;//声明了一个pt指针,四个字节,放在栈里面的
pt = new int;// new了一个int形的数据放在堆里面,再把这个数据的地址赋给pt。
这句话的意思是你先声明了一个pt指针,四个字节,放在栈里面的,然后你new了一个int形的数据放在堆里面,再把这个数据的地址赋给pt。
delete pt;
这个就是把pt指向的地址所占的内存释放掉。其实释放的就是堆上面的那个int。然后你的pt还是存在的,还在栈里面。不过你查它的值时,变成了null
这样说懂了吧。
其实你程序里面的del是在别的地方new了。
就比如:
int * A()
{
int *pt = new int;
return pt;
}
main()
{
int * ptMain;
ptMain = A();
delete ptMain;
}
这样一个过程,就像你给出的例子了。
不过,我们编程的时候尽量 谁new的谁delete,尽量避免内存泄露。
C++ 方式的内存分配与释放 new 和 delete在内存管理上,C++ 和 C 有着完全不同的两套方案。当然,C++的总是同时兼容C。C的那一套方案在C++里同样可行。 我们首先看看纯C++的那一套: new 和 delete。
new ,从字面上看意思为 “新”;而delete 字面意思为“删除”。二者在C++中内存管理中大致的功能,应是一个为“新建”,一个为“删除”。
20.2.1 newnew 是 c++ 的一个关键字。被当作像 +、-、* 、/ 一样的操作符。它的操作结果是在申请到一段指定数据类型大小的内存。
语法:
指针变量 = new 数据类型;
new 将做三件事:
1、主动计算指定数据类型需要的内存空间大小;
2、返回正确的指针类型;
3、在分配内存的一,将按照语法规则,初始化所分配的内存。
这是什么意思呢?看看例子吧:
int* p;
p = new int;
和以往不一样,p 这回不再“寄人篱下”,并不是指向某个已存在的变量,而是直接指向一段由new 分配而来的新内存空间。
“p 指向一段由new 分配而来的新内存空间” 这句话等同于:
“new 分配一段新的内存空间,然后将该内存空间的地址存入到变量p中。”
所以,最终p中仍然是存储了一个变量的地址,只是,这是一个“无名”变量。
指向原有的某个变量,和指向一段新分配的内存空间,有什么区别呢?
“原有的变量”,可以比喻成指向一间原有的,并且有主的房间。而“新分配的内存空间”,则像是一个“临时建筑物”。我们必须在不用它的时候,主动将它拆迁。拆迁的工作由delete来完成。
当指针变量通过 new ,而得到一个内存地址后,我们就可以像以前的所说的,通过该指针,通过*号,而对该内存地址(一个无名的变量),进行操作。
如:
int* p = new int;
*p = 100;
cout << *p << endl;
屏幕将输出100。
20.2.2 在new 时初始化内存的值new 也可以在申请内存空间时,直接设置该段内存里要放点什么.
语法:
指针变量 = new 数据类型(初值);
这样,上例可以改为:
int* p = new int(100);
cout << *p << endl;
如果你申请的是字符类型的空间,并且想初始化为‘A':
char* pchar = new char('A');
20.2.3 delete语法:
delete 指针变量;
delete 将释放指定指针所指向的内存空间。
举例:
int* p;
p = new int;
*p = 100;
cout << *p << endl;
delete p;
system("PAUSE");
注意,当一个指针接受delete操作后,它就又成了一个“指向不明”的指针。尽管我们可以猜测它还是指向“原来的房子”,然而,事实上,那座“房子”已经被delete “拆迁”掉了。
20.2.4 实验: new 和 delete很简单的例子。
第一步:
首先,在CB新建一个控制台程序。然后把上一小节的代码放到main()函数内。运行。结果如下:
(new 和 delete)
按任意键退出后,保存工程(Ctrl + Shift + S)。
第二步:
接下来我们来观察指针变量被delete之后,所指向的内存会是什么。但,这是一件犯了C、C++编程大忌的事:访问一个已经delete的指针的值。如果你最近运气很差,你的CB可能会被强行退出。所以,你明白我们为什么要先存盘了,对不?
在前面的代码中,加入以下加粗加红的一行(同时,你也应注意我的加的注释):
int* p;
p = new int;
*p = 100;
cout << *p << endl;
delete p; //p所指向的内存空间已经被释放
cout << *p << endl; //我们故意去访问此时p所指的内存
system("PAUSE");
运行结果:
(访问delete之后的指针)
44244844??在你的机器可能不是这个数,但一定同样是怪怪的值。 原来是好端端的100,现在却成了44244844。不要问我这是为什么?昨天来时,美眉还住在这里一座别致小阁楼里,今日故地重游,这里竟成废墟一片,依稀只见破墙上尚有:“拆!——城建局”的字样?!
new 是管建房的,而 delete就一个字:拆!
请大家自行在CB上完成本实验。我没有提供本题的实际工程。
20.2.5 new 和 delete 的关系如果只有“建房”而没有“拆房”,那么程序就会占用内存越来越多。所以,当使用new 为某个指针分配出内存空间后,一定要记得在不需要再使用时,用delete 删除。下面是一个例子。演示new 和 delete 的对应使用。
//建屋和入住:
1) int* p = new int(100);
//使用:
2) cout << *p << endl;
//拆:
3) delete p;
看,第1句,申请了4字节的内存空间,同时存入值为100的整数。
第2句,在屏幕上输出入住者的值 (100)。
第3句,释放内存(这4字节被系统收回准备做其它用途)。入住者呢?自然消失了。
前面举的例子都是在 new 一个 int 类型,其它类型也一样:
char* a = new char('A');
cout << *a << endl;
*a = 'B';
cout << *a << end;
delete a;
bool* b = new bool;
*b = true;
if (*b)
cout << "true"<< endl;
else
cout << "fale" <<endl;
但是这些都是简单数据类型,如果要分配数组一样的连续空间,则需要使另一对武器。
20.3 new [] 和 delete []new / delete 用于分配和释放单个变量的空间,而 new[] / delete[] 则用于分配连续多个变量的存间。
20.3.1 new[] / delete[] 基本用法new[] 语法:
指针变量 = new 数据类型[元素个数]
语法实例:
int* p = new int[20];
首先,你需要迅速回想一下,如果是 int* p = new int(20); 那么该是什么作用?否则你很容易在事后把二者混了。
实例中,用 new 申请分配了20个连续的整数所需的空间,即:20 * sizeof(int) = 80个字节。
图示为:
(指针变量p指向一段连续的内存空间)
new int 只是分配了一个整数的内存空间,而 new int[N]却分配了N个整数的连续空间。看来,new[] 比new “威力更猛”,所以,我们同样得记得:用 new [] 分配出空间,当不在需要时,必须及时调用 delete [] 来释放。
delete[] 语法:
delete [] 指针变量;
如:
//分配了可以存放1000个int的连续内存空间:
int* p = new int[1000];
//然后使用这些空间:
……
//最后不需要了,及时释放:
delete[] p;