动态数组new、allocate
2015-09-10 17:04
543 查看
new和delete运算符一次分配/释放一个对象,但某些应用需要一次为很多对象分配内存的功能
C++提供了两种一次分配一个对象数组的方法
new表达式语法,可以分配并初始化一个对象数组
allocate类可以将分配和初始化分离
涉及到分配动态数组的类必须定义自己版本的操作,在拷贝、复制以及销毁对象时管理所关联的内存
下例中new分配要求数量的对象,假如分配成功,并返回指向的第一个对象的指针
可以使用类型别名表示数组类型来分配一个数组,这样new表达式中不需要方括号
上述代码中编译器执行的形式是
由于分配的内存不是一个数组类型,一次不能对动态数组调用begin或end。这些函数使用数组维度来返回指向首元素和尾后元素的指针
可以对数组中的元素进行值初始化,方法是在大小之后跟一对空括号
新标准中可以用元素初始化器的花括号列表
第二条语句销毁pa指向的数组中的元素,并释放对应内存
数组中元素按照逆序销毁
空方括号对只是编译器此指针指向一个对象数组的第一个元素
对于使用类型别名定义的数组类型,在new表达式中不使用[],但是销毁时也必须使用方括号
类型说明符中的[]说明up是一个指向一个int数组而不是一个int,由于up指向一个数组,当up销毁它管理的指针时,自动使用delete[ ]
当unique_ptr指向一个数组时,可以使用下标运算符来访问数组的元素
share_ptr不能直接指向动态数组,需要提供自己定义的删除器
share_ptr不直接支持动态数组的下标运算,其访问元素可以先获得内置指针
allocate类<
4000
/h3>
new有一些灵活性上的局限,其中一方面表现在它将内存分配和对象构造结合在一起
当分配大块内存时,我们计划在这块内存上按需构造对象,我们需要将内存分配和对象构造分离
那些没有默认构造函数的类不能用new动态分配数组
提供一种类型感知的内存分配方法,其分配的内存是原始的,未构造的
aloocator是一个模板,当一个allocator对象分配内存时,其根据给定对象类型确定恰当的内存大小和对其位置
定义名为a的allocator对象,它可以为类型为T的对象分配内存
分配一段原始的、未构造的内存,保存n个类型为T的对象
释放从T*指针p中地址开始的内存,这块内存保存了n个类型为T的对象
p必须是一个先前有allocate返回的指针,且n必须是p创建时所要求的大小
在调用deallocate前,用户必须对每个在这块内存中创建的对象调用destroy
p必须为一个类型为T*的指针,指向一块原始内存
args被传递给类型为T的构造函数,用来在p指向的内存中构造一个对象
p为T*类型的指针,此算法对p指向的对象执行析构函数
construct函数接受一个指针和零个或多个额外参数,在指定位置构造一个函数
在未未构造对象的情况下使用原始内存是错误的
当用完对象后,要对每个构造的对象用destroy函数销毁他们
我们只能对真正构造了的元素进行destroy
一旦元素被销毁,可以重新使用这块内存保存其它的T
也可以将内存归还给系统,释放内存通过调用deallocate来完成
这些函数在给定目的位置创建元素,而不是由系统分配内存给他们
返回一个指针,指向最后一个构造元素之后的位置
从迭代器b和e指出的输入范围中拷贝元素到迭代器b2指定的未构造原始内存中
b2指向的内存必须足够大,能容纳输入序列中元素的拷贝
从迭代器b指向的元素开始,拷贝n个元素到b2开始的内存中
从迭代器b和e指定的原始内存范围中创建对象,对象的值均为t的拷贝
从迭代器b指向的内存开始创建n个对象,b必须指向足够大的未构造的原始内存,能够容纳给定数量的对象
C++提供了两种一次分配一个对象数组的方法
new表达式语法,可以分配并初始化一个对象数组
allocate类可以将分配和初始化分离
涉及到分配动态数组的类必须定义自己版本的操作,在拷贝、复制以及销毁对象时管理所关联的内存
new和数组
要在类型名后跟一对方括号,其中指明要分配的对象的数目下例中new分配要求数量的对象,假如分配成功,并返回指向的第一个对象的指针
int *pia = new int[get_size()];//pia指向第一个int
可以使用类型别名表示数组类型来分配一个数组,这样new表达式中不需要方括号
typedef int arrT[42];//arrT表示42个int的数组类型 int *p = new arrt;//p指向第一个int
上述代码中编译器执行的形式是
int *p = new int[42]
分配一个数组会得到一个元素类型的指针
用new分配的数组时,并未得到一个数组类型的对象,而是一个数组元素类型的指针由于分配的内存不是一个数组类型,一次不能对动态数组调用begin或end。这些函数使用数组维度来返回指向首元素和尾后元素的指针
初始化动态分配对象的数组
new分配的对象,不管是单个分配的还是数组中的,都是默认初始化的可以对数组中的元素进行值初始化,方法是在大小之后跟一对空括号
int *pia1 = new int[10]; //10个未初始化的int int *pia2 = new int[10](); //10个值初始化为0的int string *pia3 = new string[10]; //10个空的string string *pia4 = new string[10](); //10个空的string
新标准中可以用元素初始化器的花括号列表
int *pia = new int[10]{0,1,2,3,4,5,6,7};//剩下元素使用值初始化
动态分配一个空数组是合法的
不能创建一个大小为0的静态数组对象,但是当调用new[0]时时合法的:char arr[0];//错误:不能定义长度为零的数组 char* arr = new char[0];//正确,但arr不能解引用,因为它不指向任何元素
释放动态数组
在指针前加上一个空方括号对:delete p;//p指向一个动态分配的对象或为空 delete []pa;//pa必须为一个动态分配的数组或空
第二条语句销毁pa指向的数组中的元素,并释放对应内存
数组中元素按照逆序销毁
空方括号对只是编译器此指针指向一个对象数组的第一个元素
对于使用类型别名定义的数组类型,在new表达式中不使用[],但是销毁时也必须使用方括号
typedef int arrT[42];//arrT表示42个int的数组类型 int *p = new arrt;//p指向第一个int
delete []p;
智能指针和动态数组
标准库提供了一个可以管理new分配的数组的unique_ptr版本:unique_ptr<int[]> up(new int[10]);//up指向一个包含10个未初始化int的数组 up.releasr();//自动用delete[]销毁其指针
类型说明符中的[]说明up是一个指向一个int数组而不是一个int,由于up指向一个数组,当up销毁它管理的指针时,自动使用delete[ ]
当unique_ptr指向一个数组时,可以使用下标运算符来访问数组的元素
for(size_t i =o;i != 10; ++i){ up[i] = i; }
share_ptr不能直接指向动态数组,需要提供自己定义的删除器
share_ptr不直接支持动态数组的下标运算,其访问元素可以先获得内置指针
for(size_t i =o;i != 10; ++i){ *(sp.get()+i) = i; }
allocate类<
4000
/h3>
new有一些灵活性上的局限,其中一方面表现在它将内存分配和对象构造结合在一起
当分配大块内存时,我们计划在这块内存上按需构造对象,我们需要将内存分配和对象构造分离
那些没有默认构造函数的类不能用new动态分配数组
allocate类
allocate类在头文件memory中,其将内存分配和对像构造分离开提供一种类型感知的内存分配方法,其分配的内存是原始的,未构造的
aloocator是一个模板,当一个allocator对象分配内存时,其根据给定对象类型确定恰当的内存大小和对其位置
allocate<string> alloc; //可以分配string的allocator对象 auto const p = alloc.allocate(n); //分配n个未初始化的string
allocator<T> a
定义名为a的allocator对象,它可以为类型为T的对象分配内存
a.allocate(n)
分配一段原始的、未构造的内存,保存n个类型为T的对象
a.deallocate(p,n)
释放从T*指针p中地址开始的内存,这块内存保存了n个类型为T的对象
p必须是一个先前有allocate返回的指针,且n必须是p创建时所要求的大小
在调用deallocate前,用户必须对每个在这块内存中创建的对象调用destroy
a.construct(p,args)
p必须为一个类型为T*的指针,指向一块原始内存
args被传递给类型为T的构造函数,用来在p指向的内存中构造一个对象
a.destroy(p)
p为T*类型的指针,此算法对p指向的对象执行析构函数
allocator分配为构造的内存
allocator分配的内存时未构造的,我们需要再次内存中构造对象construct函数接受一个指针和零个或多个额外参数,在指定位置构造一个函数
在未未构造对象的情况下使用原始内存是错误的
当用完对象后,要对每个构造的对象用destroy函数销毁他们
我们只能对真正构造了的元素进行destroy
一旦元素被销毁,可以重新使用这块内存保存其它的T
也可以将内存归还给系统,释放内存通过调用deallocate来完成
拷贝和填充未初始化内存的算法
标准库为allocator类定义了两个伴随算法,在未初始化的内存中创建对象,它们都定义在memory头文件中这些函数在给定目的位置创建元素,而不是由系统分配内存给他们
返回一个指针,指向最后一个构造元素之后的位置
uninitialized_copy(b,e,b2)
从迭代器b和e指出的输入范围中拷贝元素到迭代器b2指定的未构造原始内存中
b2指向的内存必须足够大,能容纳输入序列中元素的拷贝
uninitialized_copy(b,n,b2)
从迭代器b指向的元素开始,拷贝n个元素到b2开始的内存中
uninitialized_fill(b,e,t)
从迭代器b和e指定的原始内存范围中创建对象,对象的值均为t的拷贝
uninitialized_fill(b,n,t)
从迭代器b指向的内存开始创建n个对象,b必须指向足够大的未构造的原始内存,能够容纳给定数量的对象
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- some new eigrp feature
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- .net(c#)中的new关键字详细介绍
- C++联合体转换成C#结构的实现方法
- Rails Routes中new、collection、member的区别浅析
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例