27. 区分内存分配的方式

c++中内存分为5个不同的区

①栈区

栈是一种特殊的数据结构,其存取数据特点为(先进后出,后进先出)。栈区中主要用于存储一些函数的入口地址,函数调用时的实参值以及局部变量。栈区的大小和内存分配由编译器和底层硬件配合完成在函数调用时发挥很大作用,但是程序员不需要关心其的操作(因此起较安全)。

②堆区

堆区主要是用户自由分配内存的区域,new(malloc())与delete(free())运算符都是在操作这块区域。因为堆区中内存的申请和释放都是交给程序员自己完成所以比较危险,容易出错。在程序结束后所有没有释放的区域都会被操作系统自动回收。

③全局/静态存储区

即全局变量和静态变量所在的内存区域。

④常量存储区

即常量所在的内存区域,其内存中的数据一旦初始化就不能被更改。

⑤代码区

顾名思义即为程序代码加载入内存的区域。

28. new/delete与new[ ]/delete[ ]必须配对使用

因为new向堆区动态申请一个对象的空间,delete是动态释放一个对象的内存空间,

而new[ ]是向堆区动态申请对个对象的空间,delete[ ]是动态释放多个对象的内存空间。

实际new [ ]在申请内存的同时还申请了内存保存申请对象的个数,在用delete[ ]时其会去寻找保存的这个对象个数,进行准确释放。

实际new操作基本数据类型对象,因为基本数据类型没有构造和析构函数可以用delete去释放也可以用delete[ ],但是为了规范和增加代码的可读性还是让new与delete配对使用,new[ ]和delete[ ]配对使用。

29. 区分new的三种状态

new实际有三种状态,不要认为自己对new很了解。

①new operator

第一种状态,其不能重载,其永远都会做三件事

//先为对象分配内存
void *memory = operator new (sizeof(对象类型))
//调用构造函数,初始化内存中的对象(当然对于基本数据类型是没有第二步的)
call 构造函数
//返回对象指针
对象类型 * pStr=static_cast<对象类型 *>(momory)

②operator new

第二种状态,第一种状态包含第二种状态(第一步),可以重载。

其会先向堆区寻找空闲内存,如果失败则调用new_hander函数在重复上述操作,直到抛出ball_alloc异常。

③placement new(包含在new头文件中),一般不使用。

30. new内存失败后应该如何处理

c中malloc函数申请内存失败返回一个NULL指针,可以通过检查NULL指针来处理。

c++中new,如果operator new申请内存错误其最终会抛出一个bad_alloc异常,所以这时候应是处理异常而不是检查NULL指针。

检查异常的方法为:

try
{
int* pStr=new int
}
catch(const bad_alloc& e)
{
//异常处理
}
当然在一些较老的编译器中并不支持这种,那便用检查NULL的方法。

31. 了解new_handler的所作所为

在使用operator new失败后其不是直接抛出bad_alloc异常的,其会先调用函数new_handler,这个函数进行一些操作

①使更大的内存块有效,通过在程序开始时分配一块大的内存,当调用new_handler时把其释放,这样在次operator new时就会成功了。

②装载其他的new_handler函数

因为如果当前的new_handler函数不能调用更大的内存供operator new使用,而有new_handler函数可以完成,则会调用set_new_handler函数把当前的new_handler函数换成那个函数。

③抛出bad_alloc异常

④直接调用exit( )或abort()函数结束程序。

当然可以对new_handler函数进行定制,

即利用set_new_handler函数装入新的new_handler函数。

32. 利用工具解决内存泄露

在程序的入口加上:

_CrtSerDbgFlag(	_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
| _CRTDBG_LEAK_CHECK_DF )

在程序运行结束时没有释放的内存会显示出来。

也可以通过其他工具进行解决。

33. 小心翼翼的重载operator new和operator delete

对于自定义数据类型,要想让操作符对其操作必须对其进行重载,而operator new很特殊其不需要重载就可以使用。

但是如果想对其进行重载也可以,不过一般不能将其重载为全局函数因为这样会覆盖掉所有new操作默认的operator new,一般在类中对其进行重载。

以为在调用operator new时还无this指针所以其应该重载为static类型而且规定第一个参数为size_t类型

class	A
{
public:
static void* operator new(size_t size)
static void operator delete( void *p)
};

注意重载operator new就必须重载operator delete

34. 用智能指针管理通过new创建的对象

利用智能指针类代替传统指针

auto_ptr智能指针,其包含在memory头文件中。

auto_ptr指向一个new对象,在其生命周期结束时对其所指向资源进行释放,不需要显示的使用delete。

使用方法:auto_ptr<类型> pa(new(类型))

也可以建立一个未指向任何对象的auto_ptr

auto_ptr<int> iPtr;
if(iPtr.get()==0) //不指向任何对象
{
iPtr.reset(new int(2011)) ;指向一个对象
}

也可以利用一个auto_ptr对两一个auto_ptr赋值

auto_ptr<int> iPtr2(iPtr);

这样的话iptr的资源就移交给了iPer2, iper不能再用。

auto_ptr有很多缺点,其不支持动态配置数组,在赋值时会发生权力转移,其不支持stl容器。

所以在boost中的新的智能指针有5种:scoped_ptr,scoped_array,shared_ptr,shared_array,weak_ptr

其智能指针支持stl容器,支持动态配置数组。

使用其要遵循两条规则

①smart_ptr不同于T*

smart_ptr实际是一个类(智能指针类),而T就是一个t类型的指针

所以不能用T
赋值给smatt_ptr

不能用NULL对smart_ptr的变量赋值,应该用其成员函数(因为其实一个类对象)

②不要使用临时的share_ptr对象

临时对象在函数做参数时,因为函数参数处理顺序是随机的,如果先处理其他参数,而这个参数恰好发生异常,则动态指针的临时对象new的指针无法返回,就会产生内存泄漏。

改善c++程序的150个建议(读后总结)-------27-35的更多相关文章

  1. 编写高质量代码_改善C++程序的150个建议 读书笔记

    这几天看了下这本书<编写高质量代码_改善C++程序的150个建议>,觉的蛮有收获的,再次记录下自己以前不清晰的知识点,以供学习. 编写符合标准的main函数 C语言标准规定了main函数的 ...

  2. 改善c++程序的150个建议(读后总结)-------19-26

    19. 明白在c++中如何使用c c++可以兼容c的绝大部分代码,但是还是有一部分不能兼容. c语言的编译器在调用函数时会把函数翻译成 : "_函数名",例如: int nasa( ...

  3. 改善c++程序的150个建议(读后总结)-------12-18

    12.优先使用前置操作符 #include <iostream> using namespace std; class A { private: int num; public: A op ...

  4. 改善c++程序的150个建议(读后总结)-------10-11

    10. 优化结构体中元素的布局 结构体变量所占空间大小并不是其所含类型所占字节数之和,其所占内存字节数涉及到字节对齐. 字节对齐 :变量在内存中储存都是以字节数为单位,每一个字节都有自己的地址,逻辑上 ...

  5. 改善c++程序的150个建议(读后总结)-------0-9

    0. 不要让main 函数返回 void 入口函数main()返回类型应该为 int, 即程序结束时return 0 表示程序正常返回,函数结束时 return -1 值表示程序异常返回, 如果不显式 ...

  6. 改善C++ 程序的150个建议学习之建议7:时刻提防内存溢出

    作为一个程序员,对内存溢出问题肯定不陌生,它已经是软件开发历史上存在了近40年的大难题.在内存空间中,当要表示的数据超出了计算机为该数据分配的空 间范围时,就产生了溢出,而溢出的多余数据则可以作为指令 ...

  7. 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法

    建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...

  8. 改善java程序的151个建议

    <编写高质量代码-改善java程序的151个建议> --秦小波 第一章.开发中通用的方法和准则 1.不要在常量和变量中出现易混淆的字母 long a=0l; --> long a=0 ...

  9. 编写高质量代码改善java程序的151个建议——导航开篇

    2014-05-16 09:08 by Jeff Li 前言 系列文章:[传送门] 下个星期度过这几天的奋战,会抓紧java的进阶学习.听过一句话,大哥说过,你一个月前的代码去看下,慘不忍睹是吧.确实 ...

随机推荐

  1. 10、Spring教程之整合MyBatis

    1.步骤 1.导入相关jar包 junit <dependency> <groupId>junit</groupId> <artifactId>juni ...

  2. 【linux】驱动-5-驱动框架分层分离&实战

    目录 前言 5. 分离分层 5.1 回顾-设备驱动实现 5.2 分离分层 5.3 设备 5.4 驱动 5.5 系统,模块 5.6 Makefile 参考: 前言 5. 分离分层 本章节记录实现LED驱 ...

  3. 如何使用Docker部署Go Web应用

    目录 如何使用Docker部署Go Web应用 Docker部署示例 准备代码 创建Docker镜像 编写Dockerfile Dockerfile解析 From Env WORKDIR,COPY,R ...

  4. greenplum6.14、GPCC6.4安装详解

    最近在做gp的升级和整改,所以把做的内容整理下,这篇文章主要是基于gp6.14的安装,主要分为gp,gpcc,pxf的一些安装和初始化.本文为博客园作者所写: 一寸HUI,个人博客地址:https:/ ...

  5. [递推]D. 【例题4】传球游戏

    D . [ 例 题 4 ] 传 球 游 戏 D. [例题4]传球游戏 D.[例题4]传球游戏 题目解析 设 t ( i , j ) t(i,j) t(i,j)为过了 j j j轮,轮到 i i i手上 ...

  6. 201871030125-王芬 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    实验三 软件工程结对项目 项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs ...

  7. BUAA_2020_OO_UNIT4_REVIEW&ALL_REVIEW

    OO第四单元总结&&学期总结 1. 第四单元作业总结 本单元三次作业都围绕了UML图的建模展开,第十三次作业只有类图,第十四次作业增加了顺序图和状态图,第十五次增加了部分UML规则的判 ...

  8. Tomcat集群 Nginx负载均衡 shell脚本实时监控Nginx

    第一步,安装Tomcat 系统环境:Centos7 第1步:下载tomcat安装包 tomcat官网:https://tomcat.apache.org/ 第2步:安装包上传至linux中 第3步:下 ...

  9. Mybatis3源码笔记(一)环境搭建

    1. 源码下载 地址:https://github.com/mybatis/mybatis-3.git. 国内访问有时确实有点慢,像我就直接先fork.然后从git上同步到国内的gitte上,然后在i ...

  10. Spring Cloud Alibaba(3)---Nacos概述

    Spring Cloud Alibaba(3)---nacos概述 上一篇博客讲了有关 SpringCloudAlibaba的概述,这篇开始讲SpringCloudAlibaba组件之一---Naco ...