动态数组
new和delete运算符一次分配/释放一个对象,但例如vector、string都是在连续的内存中保存他们的元素,需要一次分配许多内存。c++语言定义了new表达式语法,可以分配并初始化一个对象数组。在类中包含容器要用到new在拷贝赋值时开辟一定空间,但是一定要自己定义析构函数进行空间的释放。
new和数组
使用new开辟一个对象数组空间,要在类型名后指明分配的大小,new分配完成后会返回第一个元素的指针,如
int *p = new int[n];
int *p = new int[getsize()]; 方括号内的大小必须是整型,不必是常量
如果利用数组类型别名来分配空间,就不用加[]了,如
typedef int arr[n]; arr表示n个int的数组类型;
int *p = new arr; 分配了n个int的数组,p指向第一个int;
注* : 动态数组不是数组,只是为后续操作开辟一定的空间。不能用begin,end以及范围for来操作。
初始化动态数组
new分配的对象都是默认初始化的,可以对数组中的元素进行值得初始化,方法是在大小之后跟一对空括号;
int *p = new int[10]; 10个未初始化得int
int *p1 = new int[10](); 10个初始化为0得int
string *p2 = new string[10]; 10个空string
string *p3 = new string[10](); 10个空string
还可以用元素初始化器花括号进行元素初始化{}
int *p = new int[10]{0,1,2,3,4,5,6,7,8,9};
10个元素用元素初始化器进行初始化
string *ps = new string[10]{"a","an","the",string[3,'x']};
10个元素前4个使用初始化器进行初始化,剩余元素进行值初始化即默认初始化。
如果初始化器的值大于new开辟的空间,则初始化失败不会分配任何内存,且会抛出一个类型为bad_array_new_length的异常
释放动态数组
释放单个值直接
delete p;
释放动态数组则在delete后加一个[];
delete [] pa;
强调:new在类中开辟空间,释放时忘记加入[],或者内存分配不当,编译器不会给出错误,程序在执行过程中会产生异常。
#include<iostream>
using namespace std;
class NewTest
{
public:
NewTest(int m1,int m2)
{
m_1 = m1;
m_2 = new int(m2);
}
NewTest(const NewTest& NT)
{
m_1 = NT.m_1;
m_2 = new int(*NT.m_2);
}
~NewTest()
{
if (m_2 != NULL)
{
delete m_2;
m_2 = NULL;
}
}
int m_1;
int* m_2;
};
int main()
{
NewTest n1(1, 2);
NewTest n2(n1);
cout << n1.m_1 << " " << *n1.m_2 << endl;
cout << n2.m_1 << " " << *n2.m_2 << endl;
system("pause");
return 0;
}
智能指针unique_ptr
unique_ptr<T[]> u ; u指向一个动态分配的数组,数组元素类型为T
unique_ptr<T[]> u(p); u指向内置指针p所指向的动态分配的数组;
u[i]; 下表访问,返回u拥有的数组中位置i出的对象
u.release(); 自动用delete销毁其指针