C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)
C++语言定义了两个运算符来分配和释放动态内存:运算符new分配内存,运算符delete释放new分配的内存。
运算符new和delete
- 使用new动态分配和初始化对象
int* p = new int;
默认情况下,用new分配的对象进行默认初始化,如果动态分配的对象是一个类,则使用类的默认构造函数。而对于内置类型,它的值将是未定义的。
string* str = new string; // 初始化为空的string
int* pi= new int; // pi指向一个未初始化的int,它的值未知
我们可以使用直接初始化的方式来初始化一个new分配的对象,我们可以使用传统的圆括号形式进行构造,在新标准下,我们可以使用花括号列表来进行值初始化。
int* pi = new int(1024); // pi指向一个值为1024的int类型对象
string* ps = new string(10, '9'); // ps指向一个包含10个'9'的string对象 vector<int>* v = new vector<int> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // v指向一个vector对象,包含从0到9的10个元素
int* pi = new int(); // pi指向一个int类型对象,值为0
string* ps = new string(); // ps指向一个string对象,值为空字符串
auto p1 = new auto(obj); // p1 指向一个类型与obj类型一样的,用obj初始化的对象
auto p2 = new auto(a, b, c); // 错误,括号中只能有单一的参数
- 动态分配的const对象
const int* pci = new const int(1024); // 分配一个const int对象并初始化为1024
cosnt string* pcs = new const string; // 使用string的默认构造函数来初始化一个const string
- 内存耗尽
int* p1 = new int; // 如果分配失败,抛出一个std::bad_alloc异常
int* p2 = new (nothrow) int; // 如果分配失败,new返回一个空指针
这种阻止new抛出异常的方式我们叫做定位new, 定位new允许我们向new传递额外的参数,我们在此例中传递给new的是标准库定义的nothrow对象,它告诉编译器,如果new操作失败,不能抛出异常,在这种情况下,new会返回一个空指针。
bad_alloc和nothrow都定义在头文件 <new>中。
- 指针值和delete
int i, *pi1 = &i, *pi2 = nullptr;
double* pd = new double(33), *pd2 = pd;
delete i; // 错误,i不是一个指针
delete pi1; // 未定义,pi1指向一个局部变量
delete pi2; // 正确,释放一个空指针总是没有错误的
delete pd; // 正确,pd由new分配而来
delete pd2; // 未定义,pd2指向的内存已经被释放了
虽然一个const对象的值不能被改变,但是它本身是可以被销毁的。和其他任何动态对象一样,销毁一个const动态对象,只要delete指向它的指针即可:
const int* pci = new const int(1024);
delete pci;
- 动态对象的生存期直到被释放时为止
Foo* factory(T arg) {
/*
*/
return new Foo(arg); // 调用者负责释放此内存
}
这个函数负责分配内存,但并不负责释放它所分配的内存。factory的调用者负责在不需要此对象的时候释放它。
void use_factory(T arg) {
Foo* p = factory(arg);
// 使用p但是不delete它
} // p离开了作用域,但是它指向的内存并没有被释放
内置类型的对象被销毁时什么也不会发生,特别时,当一个指针离开其作用域时,它所指向的对象什么也不会发生。如果这个指针指向的是动态内存,那么内存不会被释放。
void use_fatory(T arg) {
Foo* p = factory(arg);
// 使用p
delete p;
}
如果还有其他代码块需要用到此指针,我们就需要将它返回给它的调用者:
Foo* use_fatory(T arg) {
Foo* p = factory(arg);
// 使用p
return p; // 调用者必须释放内存
}
- delete之后重置指针值
C++ Primer : 第十二章 : 动态内存之动态内存管理(new和delete)的更多相关文章
- C++ Primer : 第十二章 : 动态内存之动态数组
动态数组的分配和释放 new和数组 C++语言和标准库提供了一次分配一个对象数组的方法,定义了另一种new表达式语法.我们需要在类型名后跟一对方括号,在其中指明要分配的对象的数目. int* arr ...
- C++ Primer : 第十二章 : 动态内存之shared_ptr与new的结合使用、智能指针异常
shared_ptr和new结合使用 一个shared_ptr默认初始化为一个空指针.我们也可以使用new返回的指针来初始化一个shared_ptr: shared_ptr<double> ...
- C++ Primer : 第十二章 : 动态内存之shared_ptr类
在C++中,动态内存是的管理是通过一对运算符来完成的:new ,在动态内存中为对象分配空间并返回一个指向该对象的指针,delete接受一个动态对象的指针,销毁该对象,并释放该对象关联的内存. 动态内 ...
- C++ Primer : 第十二章 : 动态内存之allocator类
标准库allocator类定义在头文件 <memory>中.它帮助我们将内存分配和构造分离开来,它分配的内存是原始的.未构造的. 类似vector,allocator也是一个模板类,我们在 ...
- C++ Primer : 第十二章 : 动态内存之shared_ptr类实例:StrBlob类
StrBlob是一个管理string的类,借助标准库容器vector,以及动态内存管理类shared_ptr,我们将vector保存在动态内存里,这样就能在多个对象之间共享内存. 定义StrBlob类 ...
- C++ Primer : 第十二章 : 动态内存之unique_ptr和weak_ptr
unique_ptr 一个unique_ptr拥有它所管理的对象,与shared_ptr不同,unique_ptr指向的对象只能有一个用户.当unique_ptr被销毁后,它所指向的对象也被销毁. 定 ...
- C++Primer 第十二章
//1.标准库提供了两种智能指针类型来管理动态对象,均定义在头文件memory中,声明在std命名空间. // shared_ptr:允许多个指针指向同一个对象. // unique_ptr:独占所指 ...
- C++ Primer : 第十二章 : 文本查询程序
C++ Primer书上这个例子讲的很不错,写写帮助自己理解标准库和智能指针. .h 文件内容 #include <fstream> #include <iostream> # ...
- C++ Primer之 十二章 类
1.关于类的const对象 const对象只能调用声明为const的成员函数,在这篇csdn博客中也讨论了这个问题. 究其原因是因为 const 对象A 调用了非const函数F, F因为没有cons ...
随机推荐
- winform插入sql的事务处理
实现目的:点击按钮,原子性执行两条sql语句,同时成功或同时失败 数据库有这三个字段(忽略已有的一条记录): 一.用事务的sql语句 按钮事件完整代码: //事务处理插入sql语句 using (SQ ...
- swift语言之多线程操作和操作队列(上)———坚持51天吃掉大象
欢迎有兴趣的朋友,参与我的美女同事发起的活动<51天吃掉大象>,该美女真的很疯狂,希望和大家一起坚持51天做一件事情,我加入这个队伍,希望坚持51天每天写一篇技术文章.关注她的微信公众号: ...
- JVM-运行时数据区
运行时数据区示意图 ...
- 立体透视 perspective transform-style 倾斜旋转
1.perspective 是设置镜头距离,距离越远视图越小,视图越近,视图越大.就像相机焦距一样.其只对子元素产生效果. 2.transform-style: preserve-3d 设置3d效果, ...
- POJ 2752 - Seek the Name, Seek the Fame (KMP)
题意:给一个字符串s,问s的某个前缀与后缀相同的情况时,长度是多少. 此题使用KMP的next数组解决. next数组中,j=next[i],next[i]表示S[0...i-1]的某个后缀(字符串S ...
- (转)js函数参数设置默认值
原文:http://www.cnblogs.com/RightDear/archive/2013/06/26/3156652.html js函数参数设置默认值 php有个很方便的用法是在定义函数时 ...
- Ubuntu安装samba的问题
问题: root@ubuntu:~# apt-get install samba 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... 完成 有一些软件包无法被安装.如果 ...
- js 检测 flash插件以及版本号 通用所有浏览器
var fls = flashChecker(); if (fls.h) { if (fls.v < parseFloat('8.0')) { alert("您当前的flash pla ...
- Python的文件类型
Python的文件类型主要分为3种:源代码(source file).字节码(byte-code file).优化的字节码(optimized file).这些代码都可以直接运行,不需要编译或者连接. ...
- 数组Mex
题目描述 请设计一个高效算法,查找数组中未出现的最小正整数. 给定一个整数数组A和数组的大小n,请返回数组中未出现的最小正整数.保证数组大小小于等于500. 测试样例: [-1,2,3,4],4 返回 ...