目录
1. new & delete
1.1 new
- 使用new可以在程序运行时分配内存,为数据对象分配内存的通用格式为:typename * pointer_name = new typename
- 需要指定分配的内存的存放数据类型以及指针变量关联的数据类型
- new出来的内存没有名字,只能通过其返回的指针对其进行管理
- 使用new分配的内存块与常规变量分配的内存区别:(1)常规变量的内存在编译时就分配好,其内存是在栈(stack)中;(2)使用new是在程序运行时分配内存,其内存是在堆(heap)或自由存储区(free store)中。
- Q:(1)堆和栈空间有何不同?(2)new出来的内存和常规变量的内存为什么分别从堆和栈里面分配?(3)new是如何分配内存的?
- A:暂无
1.2 delete
- 使用delete释放内存:使用new分配的内存由delete释放。如果只有new而没有delete,将会发生内存泄漏(memory leak),即new出去的内存没有回归内存池,也就无法再次被new出去使用。
- delete使用格式:delete 指针变量,指针变量指向的是new出来内存的地址,不能是常规变量的地址。
1.3 使用new和delete的注意事项
- 不要使用delete来释放不是new分配的内存:new分配的内存一定要由delete释放,而delete只能释放new分配的内存。
- 不要使用delete释放已经释放的内存,这样做的结果将是不确定的
- 如果使用new [ ]为数组分配内存,则应该使用delete [ ]来释放
- 如果使用new为一个实体分配内存,则应使用delete(无方括号)释放
- 对空指针应用delete是安全的
1.4 例
1.4.1 copy书本上的代码:动态分配数组
void App(int* & pa, int len);
int main()
{
int* ary = NULL, * t;
int i, n;
cout << "n=";
cin >> n;
App(ary, n);
for (t=ary; t < ary+n; t++)
{
cout << *t << " ";
}
cout << endl;
for (i = 0; i < n; i++)
{
ary[i] = 10 + i;
}
for (i = 0; i < n; i++)
{
cout << ary[i] << " ";
}
cout << endl;
delete[]ary;
ary = NULL;
}
void App(int * & pa,int len)//这里pa的参数类型需是指针引用参数
{
pa = new int[len];
if (pa==NULL)
{
cout << "allocation faiure\n";
return;
}
for (int i = 0; i < len; i++)
{
pa[i] = 0;
}
}
分析:
- 动态分配的数组可以使用下标访问,也可以使用指针访问
- 动态分配数组的格式:类型 * pointer = new 类型[数组长度]
- 释放动态数组:delete [ ]指针
- 为了防止内存泄漏,使用指针访问时将ary的值赋给t,否则最后delete掉的不是指向new出来的动态数组
- App函数中pa使用指针引用参数,如果不用引用参数,ary只是将它的值传给pa,即pa=NULL,但是pa接受到的动态数组的地址不能传给ary,当App调用完之后,pa就会被系统释放(可以将其理解为 一个局部变量)。结果就是ary的值仍然是NULL,而new出来的动态数组无法被delete掉,因为pa已经被被系统释放。如果不用引用参数,App()函数需返回动态数组的指针给ary。
1.4.2 copy书本代码:基本类型
int main()
{
int* p = NULL;
p = new int(100);
if (p==NULL)
{
cout << "allocation faiure\n";
}
else
{
cout << *p << endl;
delete p;
p = NULL;
}
}
分析:
- 基本类型使用new申请空间:类型 * 指针变量名 = new 类型(初始值)
- 可以使用括号初始化申请内存的值
- delete完之后,指针变量并没有消失,此时将其赋NULL,清除原来的地址值,以免二次释放内存