【C++】《Effective C++》第八章
第八章 定制new和delete
对于程序开发来说,了解C++内存管理例程的行为是非常重要的。其中两个主角是分配例程和归还例程(operator new和operator delete),配角是new-handker,这是当operator new无法满足客户的内存需求时所调用的函数。
注意:STL容器所使用的heap内存是由容器所拥有的分配器对象(allocator objects)管理,不是被new和delete直接管理。
条款49:了解new-hander的行为
请记住
set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。Nothrow new是一个颇为局限的工具,因为它只适用于内存分配;后继的构造函数调用还是可能抛出异常。
条款50:了解new和delete的合理替换机制
一般处于下列原因可能想要替换编译器提供的operator new和operator delete:
- 为了检测运用错误。
- 为了收集动态分配内存的使用统计信息。
- 为了增加分配和归还的速度。
- 为了降低缺省内存管理器带来的空间额外开销。
- 为了弥补缺省分配器中的非最佳齐位。
- 为了将相关对象成簇集中。
- 为了获得非传统的行为。
下面是一个”为了检测运用错误“而实现的简单的 operator new 的例子,通过在首部和尾部插入一个签名,返回中间内存块给程序使用,如果程序在使用内存时发生过在区块前或区块后写入的行为,那么签名就会被修改,因此可以检测这种行为:
static const int signature = 0xDEADBEEF; // 边界符
typedef unsigned char Byte;
void* operator new(std::size_t size) throw(std::bad_alloc) {
// 多申请一些内存来存放占位符
size_t realSize = size + 2 * sizeof(int);
// 申请内存
void *pMem = malloc(realSize);
if (!pMem) throw bad_alloc();
// 写入边界符
*(reinterpret_cast<int*>(static_cast<Byte*>(pMem)+realSize-sizeof(int)))= *(static_cast<int*>(pMem)) = signature;
// 返回真正的内存区域
return static_cast<Byte*>(pMem) + sizeof(int);
}
这个例子主要是展示,它存在很多错误:
- 所有的
operator new都应该内含一个循环,反复调用某个new-handling函数,这里却没有。 C++要求所有operator new返回的指针都有适当的对齐。这里malloc返回的指针是满足要求的,但是因为上述实现并不是直接返回malloc的结果,而是返回一个int偏移后的地址,因此无法保证它的安全。
请记住
- 有许多理由需要自定的
new和delete,包括改善效能、对heap运用错误进行调试、手机heap使用信息。
条款51:编写new和delete时需固守常规
请记住
operator new应该包含一个无穷循环,并在其中尝试分配内存,如果它无法满足内存要求,就该调用new-handler。它也应该有能力处理0bytes申请。Class专属版本则还应该处理"比正确大小更大的(错误)申请"。operator delete应该在收到null指针时不做任何事。Class专属版本则还应该处理"比正确大小更大的(错误)申请"。
条款52:写了placement new也要写placement delete
请记住
- 当你写一个
placement operator new,请确定也写出类对应的placement operator delete。如果没有这样做,你的程序可能会发生隐蔽而时断时续的内存泄漏。 - 当你声明
placement new和placement delete,请确定不要无意识(非故意)地遮掩了它们的正常版本。
【C++】《Effective C++》第八章的更多相关文章
- 【C++】《C++ Primer 》第十八章
第十八章 用于大型程序的工具 大规模应用程序的特殊要求包括: 在独立开发的子系统之间协同处理错误的能力. 使用各种库进行协同开发的能力. 对比较复杂的应用概念建模的能力. 一.异常处理 异常处理(ex ...
- c++ primer plus(文章6版本)中国版 编程练习答案第八章
编程练习答案第八章 8.1写输出字符串的函数,存在默认参数表示输出频率,莫感觉1.(原标题太扯了,的问题的细微变化的基础上,含义) //8.1编写一个输出字符串的函数.有一个默认參数表示输出次数,默觉 ...
- C++ Primer Plus学习:第八章
C++入门第八章:函数探幽 本章将介绍C++语言区别于C语言的新特性.包括内联函数.按引用传递变量.默认的参数值.函数重载以及函数模板. 1 C++内联函数 内联函数是C++为提高程序运行速度所做的一 ...
- 【C++】《C++ Primer 》第八章
第八章 IO库 一.IO类 1. 标准库定义的IO类型 头文件 作用 类型 iostream 从标准流中读写数据 istream, wistream 从流读取数据 ostream, wostream ...
- C++Primer 第十八章
//1.异常:待研究 //2.命名空间: // A:多个库将名字放置在全局命名空间中将引发命名空间污染. // B:命名空间为防止名字冲突提供了更加可控的机制.命名空间分割了全局命名空间,其中每个命名 ...
- C++ Primer:第八章:IO库(续)
二:文件输入输出. (1) 使用文件流对象: 头文件fstream定义了三个类型来支持文件IO:ifstream从一个给定的文件中读取数据,ofstream向一个给定的文件中写入数据,以及fstrea ...
- C primer plus 读书笔记第八章
本章的标题是字符输入/输出和输入确认.主要内容是讨论用于I/O的标准函数. 1.getchar()和putchar() 这两个函数之前用过,我们通过这两个函数来讨论下缓冲区. #include &qu ...
- C++ primer 中文第三版 阅读笔记 第八章
一.寄存器对象: 函数中频繁被使用的变量可以加上register就可声明为寄存器对象.对于寄存器对象,假如能够放到寄存器中就会放到寄存器中,放不到的话就放到内存中.比如 register int a ...
- C++ Primer的课后规划问题的第八章
1.写通常需要一个参数(字符串的地址).字符串和打印功能. 只要.假设提供了第二个参数(int种类),而这个参数不0,的次数的函数打印串数量为该功能将被称为(意,字符串的打印次数不等于第二个參数的值. ...
- c primer plus(五版)编程练习-第八章编程练习
1.设计一个程序,统计从输入到文件结尾为止的字符数. #include<stdio.h> int main(void){ int ch; int i; i=; while((ch = ge ...
随机推荐
- 题解-Sakuya's task
题面 Sakuya's task \[\left(\sum_{i=1}^n\sum_{j=1}^n \varphi(\gcd(i,j))\right)\bmod 10^9+7 \] 数据范围:\(1\ ...
- HDU3306 Another kind of Fibonacci
本篇题解用于作者本人对于矩阵乘法的印象加深,也欢迎大家的阅读. 题目大意 众所周知,斐波那契数列为 \(f(0)=1\) , \(f(1)=1\) ,\(f(n)=f(n-1)+f(n-2)~(n&g ...
- 第三方模块Gulp
1.第三方模块Gulp 基于node平台开发的前端构建工具. 将机械化操作编写成任务,想要执行机械化操作时执行一个命令,命令任务就能自动执行了.提高开发效率. 1)Gulp使用 ① 使用npm ins ...
- Java并发编程的艺术(四)——JMM、重排序、happens-before
什么是JMM JMM就是Java内存模型.目的是为了屏蔽系统和硬件的差异,让同一代码在不同平台下能够达到相同的访问结果.规定了线程和内存之间的关系. 内存划分 JMM规定了内存主要划分为主内存和工作内 ...
- 大白话详解大数据hive知识点,老刘真的很用心(2)
前言:老刘不敢说写的有多好,但敢保证尽量用大白话把自己复习的内容详细解释出来,拒绝资料上的生搬硬套,做到有自己的了解! 1. hive知识点(2) 第12点:hive分桶表 hive知识点主要偏实践, ...
- WebService-问题
1.引用问题 在用C#对接webservice的时候,常用的方法是下载vs中引用webservice的地址.然后,new对应的client就可以使用了.但在,实际应用中往往会遇到webservice访 ...
- 在线CC攻击网站源码
源码目录 index.html 首页 cc.php 核心文件 count.php 使用统计 pv.php 访问测试页面 ip.txt 代理IP数据文件 运行方式 域名/?url=目标网址 要先获取代{ ...
- 使用OpenSSL自建一个HTTPS服务
1. 理论知识 1.1 什么是https 传统的 HTTP 协议以明文方式进行通信,不提供任何方式的数据加密,很容易被中间攻击者破解通信内容或者伪装成服务器与客户端通信,在安全性上存在很大问题. HT ...
- 【C#】DockPanelSuite 中 DockState.Document 状态下子窗体控件不显示的解决方案
DockPanelSuite 是 Winform 中优秀的布局控件,但是这次使用过程中却出了个问题. 我遇到的问题是这样的,主窗体是通过 ShowDialog 显示的,子窗体的停靠状态为 DockSt ...
- 史上最全Xshell and Xftp 工具的使用
文章目录 什么是xshell 解决: 安装Xshell Xshell怎么建立连接 Xshell如果修改已有连接信息? 修改,背景色,字体,编码 Xshell导出已有的登录信息 Xftp的使用 XFP建 ...