六一的部落格


关关难过关关过,前路漫漫亦灿灿。




使用内置指针管理动态数组

  • 使用 new[] 为动态数组申请内存, 返回指向首元素的指针
  • 使用 delete[] 销毁动态数组时, 传入指向首元素的指针

使用 new[] 创建动态数组

new[] 返回指向首元素的指针, 该指针不是数组指针 :

  1. 不能对其执行begin和end操作
  2. 不能对其使用范围for
-
默认初始化 new + 类型 + [n]
直接初始化 new + 类型 + [n] + ( + )
列表初始化 new + 类型 + [n] + { + 初始化列表 + }
1T *pa = new T[n];
2T *pa = new T[n]();
3T *pa = new T[n]{v1, v2...};

示例

1int *pia = new int[10];
2string *psa = new string[10];
3
4for (auto i = 0; i < 10; ++i)
5  cout <<"No " << i + 1 << ": " << pia[i] << endl;
6
7for (auto i = 0; i < 10; ++i)
8  cout <<"No " << i + 1 << ": " << psa[i] << endl;
1int *pia = new int[10]();
2string *psa = new string[10]();
3
4for (auto i = 0; i < 10; ++i)
5  cout <<"No " << i + 1 << ": " << pia[i] << endl;
6
7for (auto i = 0; i < 10; ++i)
8  cout <<"No " << i + 1 << ": " << psa[i] << endl;
1int *pia = new int[10]{1, 2, 3};
2string *psa = new string[10]{string(10, 't'), "hello"};
3
4for (auto i = 0; i < 10; ++i)
5  cout <<"No " << i + 1 << ": " << pia[i] << endl;
6
7for (auto i = 0; i < 10; ++i)
8  cout <<"No " << i + 1 << ": " << psa[i] << endl;

遍历动态数组

1int *p = new int[n];
2for (int *q = p; q != p + n; ++q)
3{
4    /* 处理数组元素 */
5}

数组大小可以为0,返回尾后指针

1auto p = new T[0];
2auto p = new T[0]();
1char *cp = new char[0];

使用 delete[] 销毁动态数组

-
delete + [] + 指向动态数组第一个元素的指针
1T *pa = new T[n];
2delete [] pa;

接受一个空指针,或者指向动态数组的第一个元素

如果指针指向单个动态对象,行为未定义

如果指针指向动态数组首元素外的其他元素,行为未定义

如果使用delete销毁动态数组,行为未定义


示例

1typedef int arrT[42];
2int *p = new arrT;
3delete [] p;

使用shared_ptr管理动态数组

通过删除器和get操作间接管理动态数组

  1. 使用删除器销毁动态数组
    1shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
    2sp.reset();
  2. 通过get操作访问数组元素
    1for (size_t i = 0; i != 10; ++i)
    2    *(sp.get() + i) = i;
    3
    4// sp.get()返回指向数组首元素的指针
    

使用unique_ptr管理动态数组

直接管理动态数组


创建动态数组

[] 指示unique_ptr指向动态数组

  1. 使用 new[] 申请动态数组
    1unique_ptr<T []> u;
    2unique_ptr<T []> u(new T[n]);
    3auto p = unique_ptr<T []>(new T[n]);
  2. 接受一个指向动态数组首元素的内置指针
    1auto p = new T[n];
    2
    3unique_ptr<T []> u(p);              // 直接初始化
    4auto u = unique_ptr<T []>(p);       // 拷贝初始化
    

赋值操作

1auto p = new T[n];
2unique_ptr<T []> up;
3up = unique_ptr<T []>(p);

使用release操作销毁动态数组

  1. 管理单个对象的unique_ptr对象调用release操作并不释放资源,用以交接资源
  2. 管理动态数组的unique_ptr对象调用release操作等价于用delete[]销毁动态数组
1u.release();

访问数组元素

支持下标运算符

1u[i];

成员访问运算符 -> 和点运算符 . 不符合上下文语义, 不予支持


动态数组



使用内置指针管理动态数组

  • 使用 new[] 为动态数组申请内存, 返回指向首元素的指针
  • 使用 delete[] 销毁动态数组时, 传入指向首元素的指针

使用 new[] 创建动态数组

new[] 返回指向首元素的指针, 该指针不是数组指针 :

  1. 不能对其执行begin和end操作
  2. 不能对其使用范围for
-
默认初始化 new + 类型 + [n]
直接初始化 new + 类型 + [n] + ( + )
列表初始化 new + 类型 + [n] + { + 初始化列表 + }
1T *pa = new T[n];
2T *pa = new T[n]();
3T *pa = new T[n]{v1, v2...};

示例

1int *pia = new int[10];
2string *psa = new string[10];
3
4for (auto i = 0; i < 10; ++i)
5  cout <<"No " << i + 1 << ": " << pia[i] << endl;
6
7for (auto i = 0; i < 10; ++i)
8  cout <<"No " << i + 1 << ": " << psa[i] << endl;
1int *pia = new int[10]();
2string *psa = new string[10]();
3
4for (auto i = 0; i < 10; ++i)
5  cout <<"No " << i + 1 << ": " << pia[i] << endl;
6
7for (auto i = 0; i < 10; ++i)
8  cout <<"No " << i + 1 << ": " << psa[i] << endl;
1int *pia = new int[10]{1, 2, 3};
2string *psa = new string[10]{string(10, 't'), "hello"};
3
4for (auto i = 0; i < 10; ++i)
5  cout <<"No " << i + 1 << ": " << pia[i] << endl;
6
7for (auto i = 0; i < 10; ++i)
8  cout <<"No " << i + 1 << ": " << psa[i] << endl;

遍历动态数组

1int *p = new int[n];
2for (int *q = p; q != p + n; ++q)
3{
4    /* 处理数组元素 */
5}

数组大小可以为0,返回尾后指针

1auto p = new T[0];
2auto p = new T[0]();
1char *cp = new char[0];

使用 delete[] 销毁动态数组

-
delete + [] + 指向动态数组第一个元素的指针
1T *pa = new T[n];
2delete [] pa;

接受一个空指针,或者指向动态数组的第一个元素

如果指针指向单个动态对象,行为未定义

如果指针指向动态数组首元素外的其他元素,行为未定义

如果使用delete销毁动态数组,行为未定义


示例

1typedef int arrT[42];
2int *p = new arrT;
3delete [] p;

使用shared_ptr管理动态数组

通过删除器和get操作间接管理动态数组

  1. 使用删除器销毁动态数组
    1shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
    2sp.reset();
  2. 通过get操作访问数组元素
    1for (size_t i = 0; i != 10; ++i)
    2    *(sp.get() + i) = i;
    3
    4// sp.get()返回指向数组首元素的指针
    

使用unique_ptr管理动态数组

直接管理动态数组


创建动态数组

[] 指示unique_ptr指向动态数组

  1. 使用 new[] 申请动态数组
    1unique_ptr<T []> u;
    2unique_ptr<T []> u(new T[n]);
    3auto p = unique_ptr<T []>(new T[n]);
  2. 接受一个指向动态数组首元素的内置指针
    1auto p = new T[n];
    2
    3unique_ptr<T []> u(p);              // 直接初始化
    4auto u = unique_ptr<T []>(p);       // 拷贝初始化
    

赋值操作

1auto p = new T[n];
2unique_ptr<T []> up;
3up = unique_ptr<T []>(p);

使用release操作销毁动态数组

  1. 管理单个对象的unique_ptr对象调用release操作并不释放资源,用以交接资源
  2. 管理动态数组的unique_ptr对象调用release操作等价于用delete[]销毁动态数组
1u.release();

访问数组元素

支持下标运算符

1u[i];

成员访问运算符 -> 和点运算符 . 不符合上下文语义, 不予支持