C++,基础问题,谁能给我讲讲,new和delete的用法。不要从乱七八糟的网站复制过来,看不懂。
2013-06-17
呃,大一新生……我一时也讲不全。想到什么给你说点儿什么吧。
先说题外话,介绍一下new的功能:
C++里面引入的面向对象的概念。实例化一个对象的基本手段之一是new。new是运行时实例化一个对象。在new调用之前,这和编译时实例化一个对象是有区别的。编译时实例化一个对象,可能放在内存的数据段,也可能放在栈里。在这两个内存位置,都不适合存放频繁分配并多处使用的大数据。堆段是内存里面空闲控件最大的一个池。new的功能就是从这个内存池里面取出相应大小的内存来供程序使用。new 操作的返回是一个指针。
进入正题,new的用法是:
p_A = new A; //A是一个类型的名称,p_A是A的指针类型的变量。
比如,我们需要运行时分配一个ClassA类型的对象,
ClassA *p = NULL;
//...
p = new ClassA;
当执行到第二行的时候,p获得了一个ClassA的对象的指针。代码如果没有执行到这一行,就不会生成这个对象。而且,需要注意,一旦这个对象通过new生成了,只要不通过delete释放掉,就一直存在。
再比如,我们需要一个很大的数组,
int * p_int = new int[1024];
程序执行到这里时,生成了一个很大的4k的内存空间返回给p_int,里面可以放1024个int。
刚才说过了,new分配出来的内存不delete的话,就一直被该程序占用着。
delete直接对于一个new出来的对象的指针进行操作。上面提到的三个都执行过了,而且这些指针没有被delete过。可以这样delete掉
delete p_A;
delete p;
delete [] p_int;
注意第三个,new XXX[n]出来的对象指针,需要用delete []去释放。delete和delete[]不一样,不能混用,否则出错。
new和delete的使用注意事项:
1. 不是通过new出来的对象指针,是不能delete的,如果试图去delete那样的指针,就会让程序出错发生异常。
2. new xxxx[yyy]出来的内容必须用delete[]释放。
3. 不能对一个已经释放了指针重复delete第二次。否则会发生程序异常。
4. 有new就必须有对应的delete,要确保在正确的位置delete掉。否则如果一直new不delete,就会造成内存泄漏。
5. 第4点提到正确的位置delete。因为一旦这个对象的指针已经被delete了,那段内存就被系统回收了,可能还会在后来分配到别的地方并被使用。所以,通过被delete过的指针访问已经被delete掉了的内存,可能会发生不可预知的错误。
更多的使用示例:
new ClassA(arg1, arg2); //通过调用构造函数ClassA(arg1, arg2)来new一个新对象
vector<int> *pv = new vector<int>(10, 0);//new出来一个包含10个0的vector。其实就是调用vector的接受两个整型参数的构造函数。
int *p_int = new int(10); //new出来一个整型,并初始化其值为10
P.S. new有个很不常用的用法,好像叫做 定位new。
看看这个例子你就明白了
#include <iostream>
using namespace std;
int main()
{
int a[1] = { 1 };
int *p = new(a) int;
cout << "*p = " << *p << endl;
cout << "a[0] = " << a[0] << endl;
return 0;
}
程序打印出来,你会发现,*p的内容就是a[0]的内容。因为 定位new 的用法是:
new(memory_pionter) 当作一个new运算符来用,不是在堆,而是在这个memory_pionter指向的内存空间里面分配一个对象返回其指针。这种用法太诡异了,所以很少有人用。
(全是自己敲的哟,木有从别处copy)
一般我们直接定义 int a; //这样内存就已经给他分配好空间了。不用再申请。
但是对于指针类型。 int *a ; //这样是空的。我们就得给他申请空间
int *a =new int ; //这样就给他分配了一个内存空间。
然后才可以 *a= 10 //这样赋值,表示a指针所指的内存空间值为10
用完了,就delete a; 这样就回收内存
new和delete成对出现,如果使用了new,在变量不用的时候,一定要delete
new操作的对象是指针,new操作的目的是给指针分配空间。
记住这两条,我想基本上就不会使用错误了。
int *p =new int;在堆中申请一个int型大小的内存,p指向它
delete p;将堆中申请的这个内存手动释放掉,若不手动释放则会造成内存泄露