目录
为什么分配动态内存?
在程序中处理固定数量的变量,这样的应用非常有限。经常需要在执行期间根据程序的输入数据来决定应给存储不同类型的变量分配的空间量。例如,如果需要存储一个班的学生信息,由于学生数目不固定,学生的名字长度也不一样,因此最有效的处理该数据,肯定是在执行时动态地分配空间。
显然,因为不可能在编译期间定义任何动态分配的变量,所以源程序中将没有它们的名称。当创建这些变量时,计算机用内存中相应的地址来标识它们,该地址被存储在指针中。
堆的别名——空闲存储器
在大多数情况下,当执行程序时,计算机中有部分未使用的内存。这些内存在C++中被称为堆,有时也称为空闲存储器。使用C++中的一种特殊操作符,可以在空闲存储器中为特定类型的新变量分配空间。该操作符返回分配给变量的内存地址,它就是new操作符,与其配对的是delete操作符,其作用是释放先前new分配的内存。
我们可以在程序中为某些变量在空闲存储器中分配空间,当不再需要这些变量时,再将分配的空间释放并返回给空闲存储器。这样在相同程序的后面,这部分内存就可以被其他动态分配的变量重用。这种技术非常强大,使我们可以高效地使用内存,而且在许多情况下,使用这种技术的程序可以处理许多原本不可能处理的、涉及大量数据的非常庞大的问题。
new 和 delete 操作符
假设某个double变量需要空间。我们定义一个指向double类型的指针,然后在运行时再请求分配内存。
double *p;
p = new double; //为double变量请求内存
第二行代码中的new操作符应该返回空闲存储器中分配给double变量的内存地址,并在指针p中存储该地址。也就是说,将地址赋给p,现在p是地址,而*p是存储在那里的值。之后,根据间接寻址运算符,可以通过指针p来引用double变量。
*p = 999.0;
使用new创建的变量也可以初始化。以前面new分配的double变量为例,其地址存储在p中,在创建变量的同时将其初始化:
p = new double(999.0);
当然也可以只用一条语句创建此指针并进行初始化:
double *p(new double(999.0));
当不再需要动态地分配某个变量时,可以用delete操作符将其占用的内存释放到空闲存贮器中:
delete p;
这样可以确保这块内存以后可以被另一个变量使用。如果不使用delete,随后又在p指针中存入了一个不同的地址值,那么将无法再释放这块内存,或使用其包含的变量,因为我们失去了访问该地址的途径。这种情况称为内存泄漏。
为数组动态分配内存
为数组动态分配内存也非常简单。如果我们希望分配一个char类型的数组,假设pstr是指向char类型的指针,则:
char *pstr;
pstr= new char [20];
该语句为20个字符的char数组分配空间,并将其地址存储到pstr中。
为了删除刚才在空闲存储器中创建的数组,必须使用delete操作符。
delete [] pstr;
注意,使用方括号是为了指出要删除的是一个数组。从空闲存储器中删除数组时,应该总是包括方括号,否则结果将不可预料。另外请注意,不用指定任何维数,只需写出[]即可。
当然,指针pstr现在包含的地址可能已经分配给有其他用途的变量,因此我们当然不应该再使用该指针。当使用delete操作符抛弃之前分配的某些内存后,还应该总是将该指针重新设置成nullptr:
pstr = nullptr;
这样确保我们不会试图访问已经删除的内存。
当程序结束时,系统将释放在空闲存储器中给它分配的所有内存,但养成“将不再指向有效内存区域的指针复位成nullptr”这样的习惯,是没有坏处的。
总之,使用new和delete时,应遵守以下规则:
(1)不要使用delete来释放不是new分配的内存;
(2)不要使用delete释放同一个内存块两次;
(3)如果使用new[]为数组分配内存,则应使用delete[]来释放;
例1:使用new来创建动态数组,以及使用数组表示法来访问元素。
#include<iostream>
using namespace std;
int main()
{
int i;
int *p=new int[3]; //创建指针*p,它指向包含3个int值的内存块中的第一个元素;
p[0]=1;
p[1]=2;
p[2]=3;
cout<<"p[2]="<<p[2]<<endl;
cout<<"*(p+2)="<<*(p+2)<<endl;
p=p+1; //此时指针指向数组第二个元素;
cout<<"p[0]="<<p[0]<<endl;
p=p-1; //指针指向数组第一个元素;
delete [] p; //释放内存
p=nullptr;
return 0;
}
运行程序:
参考:https://blog.csdn.net/qq_40416052/article/details/82493916