动态数组new、allocate
来源:互联网 发布:检查语法错误的软件 编辑:程序博客网 时间:2024/05/18 00:54
- new和delete运算符一次分配/释放一个对象,但某些应用需要一次为很多对象分配内存的功能
- 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个未初始化的intint *pia2 = new int[10](); //10个值初始化为0的intstring *pia3 = new string[10]; //10个空的stringstring *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指向第一个intdelete []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类
- 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必须指向足够大的未构造的原始内存,能够容纳给定数量的对象
0 0
- 动态数组new、allocate
- ALLOCATE语句分配FORTRAN动态数组方法
- 使用new创建动态数组
- C++ new 动态数组初始化
- New device resource allocate function
- New device resource allocate function
- C++ 用new 动态创建多维数组
- C++ 用new 动态创建多维数组
- C++ 用new 动态创建多维数组
- C++ 用new 动态创建多维数组
- 关于动态new二维数组的问题
- C++ 用new 动态创建多维数组
- 【C++】使用new新建动态二维数组
- c++ new/delete [],内存泄漏,动态数组
- 使用new来创建动态数组
- 【C++】使用new新建动态二维数组
- Thread 1 cannot allocate new log
- Thread 1 cannot allocate new log
- HDU 4763 Theme Section
- windows 无法安装到这个磁盘,选中的磁盘具有MBR分区表。在EFI系统上,windows只能安装在GPT磁盘上
- Centos下重要日志文件及查看方式
- IDEA编译smalidea源码
- 「分而治之」化大为小
- 动态数组new、allocate
- Visual Studio 2015 版本区别
- POJ - 2031 Building a Space Station(最小生成树简单题)
- 独立成分分析(Independent Component Analysis)
- 导航栏和状态栏
- 于java里方法的内部类只能访问被final修饰的局部变量和.
- 欢迎使用CSDN-markdown编辑器
- 使用PropertyGrid是出现无法找到System.String上的构造函数的解决方法
- 在用例图中如何区分include和extends?