C++:关于动态数组

来源:互联网 发布:东京 蓝带 知乎 编辑:程序博客网 时间:2024/05/21 21:48

关于动态数组

new和delete运算符一次分配/释放一个对象,但有时候需要一次性分配多个对象的内存。为了满足需求,C++提供两种方法来一次分配一个对象数组的方法:new表达式语法、allocator类。

一、new/delete

1、分配一个对象
int *p = new int;delete p;

2、一维动态数组
方括号内的数必须是整型,但不一定要求是常量且可以是0,这和内置数组的要求是不一样的。动态数组和内置数组是不一样的,它返回的是一个指针,不可以使用end和begin函数来求取数组的首指针和尾指针。使用delete操作符释放对象数组空间时,需要在delete添加一对不可省略的放括号[],数组元素按照逆序销毁。不添加方括号释放指向动态数组的指针是未定义的行为。默认情况下,new分配的对象都是默认初始化,因此对于内置数据类型是未定义的,而类类型会根据各自的内部机制进行初始化。因此,可以在后面添加一对圆括号或者花括号构成列表进行初始化避免未定义状况的产生。
typedef int arr[10];int *p = new arr();int *p = new int[10]{1,2,3,4};delete[]  p;
3、二维动态数组
//开辟二维动态数组空间p[m][n]int **p = new int*[m];//开辟m行for (int i = 0;i < m; ++i)       p[i] = new int[n];//开辟n列//释放空间for(i = 0; i < m; i++)          delete[] p[i];  delete[] p;
 

二、allocate/deallocate

new操作符在分配内存时进行了初始化也就是内存分配和初始化同时进行,相应地delete操作符将对象析构和内存释放进行了组合。这在有些时候有一定的局限,例如当不需要初始化那么多个数据的时候,希望将分配内存和对象构建分离的时候。定义在memory头文件中的allocator类提供了一种类型感知的内存分配方法,其分配的内存是原始的,未构造对象的。
allocator<T> a;//定义一个名为a的allocator对象,可以为类型为T的对象分配内存a.allocate(n);//分配可以存储n个T类型对象的原始内存a.deallocate(p,n);//释放内存,p为allocate返回的指针,n为开辟的内存大小。执行之前必须执行destroya.construct(p,args);//p为T*型指针,args为T型对象的构造函数,用来在p指向的内存中构造一个对象a.destroy(p);//析构p指向的对象

1、创建一个对象
int main(){allocator<int> a;auto const p = a.allocate(1);a.construct(p, 1);a.destroy(p);a.deallocate(p, 1);return 0;}


2、一维动态数组
#include<iostream>#include<memory>using namespace std;int main(){allocator<int> a;int n = 5;auto const p = a.allocate(n);auto ptr = p;for(int i = 0; i < n; ++i){a.construct(ptr+i, i);cout << ptr[i] << endl; }for(int i = 0; i < n; ++i)a.destroy(ptr++);a.deallocate(p, n);return 0;}

3、二维动态数组
#include<iostream>#include<memory>#include<iomanip>using namespace std;int main(){allocator<int*> a;int rows = 3;allocator<int> b;int cols = 4;int **p = a.allocate(rows);//开辟行for (int i = 0; i<rows; ++i )*(p+i) = b.allocate(cols);//开辟列//输入数据for (int i = 0; i < rows; ++i){for (int j = 0; j < cols; ++j){p[i][j] = i*rows + j;cout << setw(4) << p[i][j];}cout << endl;}//解析与销毁对象for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j){b.destroy(*(p + i) + j);}b.deallocate(*(p + i), cols);a.destroy(p + i);}a.deallocate(p, rows);return 0;}


三、malloc/free


1、分配一个元素
#include<iostream>using namespace std;int main(){int * p = NULL;int m = 0;p = (int*)malloc(sizeof(int));cin >> *p;free(p);return 0;}

2、一维动态数组
#include<iostream>#include<iomanip>using namespace std;int main(){int * p = NULL;int nums = 4;p = (int*)malloc(sizeof(int)*nums);//开辟空间for(int i = 0; i < nums; ++i)cin >> *(p+i);for (int i = 0; i < nums; ++i)cout<<setw(3)<< *(p+i);free(p);return 0;}

3、二维数组
#include<iostream>#include<iomanip>using namespace std;int main(){int ** p = NULL;int rows = 3;int cols = 4;p = (int**)malloc(sizeof(int*)*rows);//开辟行for(int i = 0; i < cols; ++i)p[i] = (int*)malloc(sizeof(int)*cols);//开辟列       //赋值元素for (int i = 0; i < rows; ++i)for (int j = 0; j < cols; j++)p[i][j] = i*cols + j;//输出元素for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; j++) {cout<<setw(3)<<p[i][j];}cout << endl;}for(int i =0; i < rows;++i)free(p[i]);return 0;}

四、vector

void main()  {      int m(4),n(3);      vector<vector<int>> p(m,vector<int>(n));            cout<<"请输入数据:";      for(int i = 0 ; i < m ; i++)          for(int j = 0; j < n; j++)              cin>>p[i][j];                cout<<"输出数据:"<<endl;      for(i = 0; i < m; i++)      {          for(int j = 0; j < n; j++)              cout<<setw(3)<<p[i][j];          cout<<endl;      }                }  

五、智能指针unique_ptr

1、一维数组
unique_ptr<int []> p(new int[10]);