《C++ Primer 第5版》-12.2动态数组-康奈尔笔记

《C++ Primer 第5版》-12.2动态数组-康奈尔笔记,第1张

《C++ Primer 第5版》-12.2动态数组-康奈尔笔记

12.2.1new和数组

  1. 动态数组
  2. New和数组
  3. 分配一个数组会得到一个元素类型的指针
  4. 初始化状态分配对象的数组
  5. 动态分配一个空数组是合法的
  6. 释放动态数组
  7. 只能指针和动态数组

Int *pia = new int[get_size()];

Typedef int art[42];

Int *p = new art;

Int *Pia = new int[10];

Int *pia2=new int[10]();

String *psa = new string[10];

String *psa2 = new string[10]();

Int *pia3 = new int[10]{0,1,2,3,4,5,6,7,8,9};

String *psa3 = new string[10]{“a”,”an”};

Int *p = new int[0];

Delete[] p;

Unique_ptr up(new int[10];

Up.release();//delete []

Up[i] = I;

Shared_ptr sp(new int[10],[](int *p){delete[] p;});

Sp.reset();

*(sp.get()+i_=I;

1. 动态数组

1)一次为很多对象分配内存功能

2)两种分配一个对象数组的方法,new和allocator

3)new将分配和初始化绑定在一起,没用到的内存,但是也分配了内存并且有初始值 就浪费了。allocator可将分配和初始化分离,这样更灵活

4)最好使用vector标准库容器,而不是动态分配数组,容器的类可以使用默认版本的拷贝、赋值和析构 *** 作。分配动态数组的类必须定义自己版本的 *** 作,在拷贝、复制以及销毁对象时管理所关联的内存。

5)分配动态数组的类必须定义自己版本的 *** 作,在拷贝 复制以及销毁对象时管理所关联的内存

2. New和数组

1)在类型名之后跟一对方括号,在其中指明要分配的对象的数目。分配成功返回指向第一个对象的指针

2)大小必须是整形不必是常量,也可以用一个别名。

3. 分配一个数组会得到一个元素类型的指针

1)叫 动态数组,并不是真的是数组类型的对象,而是得到一个数组元素类型的指针。即使使用类型别名,也不会得到数组类型的对象

2)因为不是数组类型,所以不能使用begin(),也不能使用for处理动态数组中的元素

4. 初始化状态分配对象的数组

1)new分配的对象,都是默认初始化,可以对数组中的元素进行值初始化,跟上空括号。

2)可以提供一个元素初始化器的花括号列表

3)初始化可以混合,前4个初始化器初始,剩下的值初始化

4)若初始化数目小于元素数目,剩余元素将进行值初始化。

      若初始化数目大于元素数目,报错,不会分配任何内存,抛出bad_array_length异常

5)不能在值初始化的括号中给出初始化器,意味着不能用auto分配数组

5. 动态分配一个空数组是合法的

1)动态分配一个空数组是合法的并且可以使用下标为0的元素,但不能解引用

2)就像尾后指针一样,可以进行比较 *** 作,可加减0;

3)不能定义长度为0的数组,但可以一个动态分配一个空数组

6. 释放动态数组

1)只删除p对象是错误的 未定义的 报错,猜想:只删除第一个元素吧? 或者销毁第一个元素并且不指向数组了所以会访问不到,但是数组依然存在除了第一个位置的

2)需要加上方括号对,按逆序销毁

3)空括号是必须的。意味p只是指向一个对象数组的首元素,而不是一个类型为arrT的的单一对象

Note:单delete p可能不发出警告,但在运行时会异常

7. 只能指针和动态数组

1)Unique可以管理new分配的数组的unique_ptr版本

2)并且可以用下标访问数组中的元素

3)Unique销毁自动调用delete[]

4)不直接支持管理动态数组,若想需要自定义删除器,使用lambda作为删除器,使用delete[]释放数组。

      若没有删除器,则默认使用delete删除对象,会未定义的

5)不提供下标访问数组的元素,而且只能指针类型不支持算术运算。需用get先获取内置指针再 *** 作

12.2allocator类

  1. allocator类
  2. allocator类2
  3. allocator分配未构造的内存
  4. 拷贝和填充未初始化内存的算法

Allocator alloc;

Auto const p = alloc.allocate(n);

Alloc.construct(q++);

Alloc.construct(q++,”hi”)

Alloc.construct(q++,10,’c’)

while (q1 != p1) {

         alloc1.destroy(--q1);// 释放构造了的string,逆序,只能对构造了的进行destory

         }

alloc1.deallocate(p1, 3);//归还内存

allocator all2;

auto p2 = all2.allocate(ve.size() * 2);

auto q2 = uninitialized_copy(ve.begin(), ve.end(), p2);//目的位置,返回的是最后一个位置

uninitialized_fill_n(q2, ve.size(), 42);//

1. allocator类

1)new 将内存分配和对象构造组合绑定了一起,delete将对象析构和内存释放组合了一起

2)希望内存分配和对象构造分离可以使用allocator类

3)列子,string被赋值了两次,一次默认初始化,一次赋值时,

     有可能没有用到内存也被附上了初始值,因为默认初始化,

     更重要的,没有默认构造函数的类无法动态分配数组。

2. allocator类2

1)头文件memory中是一个模板需指定可以分配的对象类型

2)分配的内存是原始的 未构造的

3)根据对象类型来确定恰当的内存大小和对齐位置。分配后返回第一个内存的地址吧

3. allocator分配未构造的内存

        alloc1.construct(q1++);

        alloc1.construct(q1++, 10, 'c');

        alloc1.construct(q1++, "hi");

note:用construct构造对象。若没有构造的对象的内存使用了 未定义的

note:只能对真正构造了的元素进行destroy *** 作

destroy了元素后,可以将内存归还系统。Deallocate完成。大小参数需一样,不能大于初始化的大小

4. 拷贝和填充未初始化内存的算法

1)两个伴随算法,拷贝和填充,定义在memory中

2)可以用迭代器指定位置,或者迭代器指向的内存地址+n的形式

3)Copy返回最后一个构造的元素之后的位置,fill_n不返回

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5692829.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存