C++ Primer : 第十二章 : 动态内存之动态数组
动态数组的分配和释放
- new和数组
int* arr = new int[20]; // arr 指向第一个int
方括号中的大小必须是整数,但不必是常量。
typedef int arrT[42];
int* p = new arrT; // 分配一个42个int的数组,p指向第一个int
虽然我们通常称 new T[ ] 分配的内存为 “动态数组”, 这种叫法在某种程度上来说有些误导。使用new分配一个数组时,我们只是获得了一个数组元素类型的指针,并未获得一个数组类型的对象。因此,动态数组并不是数组类型。因此,不能对动态数组使用begin()和end(),这些函数使用数组的维度,也不能处理数组中的元素,比如for语句。
- 初始化动态分配对象的数组
int* pia = new int[10]; // 10个未初始化的int
int* pia1 = new int[10](); // 10个值初始化的int
string* psa = new string[10]; // 10个空string
string* psa = new string[10](); // 10个空string
新标准中,我们可以提供一个元素初始化器的花括号列表:
int* pia2 = new int[10]{0, 1, 2, 3, 4, 5, 6};
如果花括号中的元素个数少于分配对象个数,剩余的元素进行值初始化,如果元素个数多余对象个数,则new表达式失败,不会分配内存。new会抛出一个bad_array_new_length的异常,类似bad_alloc,该异常类型定义在头文件 <new>中。
- 动态分配一个空数组是合法的
char* pc = new char(0);
此时new返回一个与其他new表达式返回类型都不同的指针类型,该指针不能解引用,就像一个数组的尾后迭代器一样。
- 释放动态数组
数组中的元素逆序销毁,即,最后一个元素首先被销毁,然后是倒数第二个,依次类推。
智能指针和动态数组
unique_ptr<int[]> up(new int[10]());
up.release(); // 自动调用delete []销毁其指针
当一个unique_ptr指向一个数组时,我们不能使用点和箭头成员运算符,毕竟,unique_ptr指向的是一个数组而不是单个对象。不过,我们可以使用下表运算符来访问数组中的元素:
for (size_t i = 0; i < 10; ++i)
up[i] = i;
shared_ptr不支持动态数组,如果希望使用shared_ptr管理一个动态数组,我们需要提供自己的删除器:
shared_ptr<int> sp(new int[10], [](int* p){ delete [] p; });
sp.reset();
我们在这个例子中使用lambda做为shared_ptr的删除器,如果我们不提供删除器,这样的行为是未定义的,因为默认情况下shared_ptr使用delete来释放内存,使用delete来释放一个动态数组的定位是未定义的。
for (size_t i = 0; i != 10; ++i)
*(sp.get() + i) = i;
shared_ptr没有定义下标运算符,而且智能指针不支持指针算术运算。因此,为了访问数组中的元素,我们必须用get成员函数获取一个内置指针,然后使用该内置指针来访问数租元素。
C++ Primer : 第十二章 : 动态内存之动态数组的更多相关文章
- C++ Primer : 第十二章 : 动态内存之shared_ptr与new的结合使用、智能指针异常
shared_ptr和new结合使用 一个shared_ptr默认初始化为一个空指针.我们也可以使用new返回的指针来初始化一个shared_ptr: shared_ptr<double> ...
- C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)
C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存. 运算符new和delete 使用new动态分配和初始化对象 在自由空间分配的内存是无名的 ...
- C++ Primer : 第十二章 : 动态内存之shared_ptr类实例:StrBlob类
StrBlob是一个管理string的类,借助标准库容器vector,以及动态内存管理类shared_ptr,我们将vector保存在动态内存里,这样就能在多个对象之间共享内存. 定义StrBlob类 ...
- C++ Primer : 第十二章 : 动态内存之shared_ptr类
在C++中,动态内存是的管理是通过一对运算符来完成的:new ,在动态内存中为对象分配空间并返回一个指向该对象的指针,delete接受一个动态对象的指针,销毁该对象,并释放该对象关联的内存. 动态内 ...
- Linux内核设计与实现 总结笔记(第十二章)内存管理
内核里的内存分配不像其他地方分配内存那么容易,内核的内存分配不能简单便捷的使用,分配机制也不能太复杂. 一.页 内核把页作为内存管理的基本单位,尽管处理器最小寻址坑是是字或者字节.但是内存管理单元MM ...
- C++Primer 第十二章
//1.标准库提供了两种智能指针类型来管理动态对象,均定义在头文件memory中,声明在std命名空间. // shared_ptr:允许多个指针指向同一个对象. // unique_ptr:独占所指 ...
- C++ Primer : 第十二章 : 动态内存之allocator类
标准库allocator类定义在头文件 <memory>中.它帮助我们将内存分配和构造分离开来,它分配的内存是原始的.未构造的. 类似vector,allocator也是一个模板类,我们在 ...
- C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr
unique_ptr 一个unique_ptr拥有它所管理的对象,与shared_ptr不同,unique_ptr指向的对象只能有一个用户.当unique_ptr被销毁后,它所指向的对象也被销毁. 定 ...
- C++ Primer : 第十二章 : 文本查询程序
C++ Primer书上这个例子讲的很不错,写写帮助自己理解标准库和智能指针. .h 文件内容 #include <fstream> #include <iostream> # ...
随机推荐
- PowerMock与EasyMock的应用(转)
Leader请求在做Junit测试的时辰,Mock掉各个办法之间的依附.这两天进修了下PowerMock的应用. PowerMock是EasyMock的一个扩大,参加了static,final,pri ...
- Fair Photography
题目大意: 给出直线上N个点的位置和颜色(0或1),求最大的区间,使得区间内0的个数大于等于1的个数且0的个数减去1的个数为偶数. 解题过程: 1.先贴个lsdsjy大牛的线段树的做法:http:// ...
- IBatis.Net 表连接查询(五)
IBatis.Net之多表查询: 一.定制实际对应类的方式 首先配置多表的测试数据库,IBatis.Net之Oracle表连接查询配置: 首先新建两张表如下: 为两张表建立外键: ALTER TABL ...
- Fragment 切换问题
public void switchContent(Fragment fragment) { if(mContent != fragment) { mContent = fragment; mFrag ...
- objective-c strong导致内存泄漏简单案例
例如: @interface Test:NSObject{ id __strong obj_; } -(void) setObject:(id __strong)obj; @end @implemen ...
- JAVA 打印九九乘法表
/** * * @author liangxiaoyu * @version 1.0 *2015-09-18 */public class JJ { public static void main( ...
- SQL优化-索引
(一)深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录.微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonc ...
- C++11 move_iterator
template<typename Iterator> class move_iterator { Iterator current; public: typedef Iterator i ...
- linux下解决端口被占用的问题
以端口9877为例,先查看是否有进程占用该端口 netstat -tln | grep 9877 然后查看占用该端口的进程的进程id lsof -i :9877 最后kill 命令结束该进程: kil ...
- __set()与__get() 魔术方法
在面向对象编程的过程中,对于类当中的各个成员变量,都有不同的访问属性,比如公有的(public)属性,在类内部和类外部都可直接调用:而私有的(private)和受保护的(protected),在类外不 ...