12.2.1new和数组
- 动态数组
- New和数组
- 分配一个数组会得到一个元素类型的指针
- 初始化状态分配对象的数组
- 动态分配一个空数组是合法的
- 释放动态数组
- 只能指针和动态数组
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.release();//delete []
Up[i] = I;
Shared_ptr
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类
- allocator类
- allocator类2
- allocator分配未构造的内存
- 拷贝和填充未初始化内存的算法
Allocator
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
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不返回
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)