网站大量收购独家精品文档,联系QQ:2885784924

VC调试基础知识.ppt

  1. 1、本文档共63页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
VC调试基础知识

VC调试基础知识 目录 复制构造函数和赋值操作符 new, new[]和delete,delete[]解析 堆栈初步认识 内存管理基础(物理内存,虚拟内存,堆的关系) 内存异常定位的不确定性 实时调试之看懂内存 实时调试之内存异常定位 华生医生日志查看 VC调试环境介绍 转储文件(*.dmp)调试 诡异现象之谜 复制构造函数和赋值操作符 现有网管代码中,有不少类或结构定义了复制构造函数和赋值操作符。 不适当的自定义的弊端 1.可维护性差,易出错,特别是当改变了成员结构,却忘记更新代码 2.性能损失 3.制造垃圾代码。 我们是否需要自定义复制行为? 复制构造函数和赋值操作符 对象默认的复制行为 1.简单类型,直接复制。 2.对象类型,调用赋值操作符,若无,采用默认复制。 3.若编译器判断该对象内存结构可直接整块复制,将优化为二进制copy。类似memcpy(). 须自定义的场景 1.存在指针,且指针是对象自身管理,对象间不共享。 2.复制时要做其他特殊操作。 复制构造函数和赋值操作符 须自定义复制构造和赋值的场景示例: class A { public: A():m_pBuffer(NULL){} ~A() { if (m_pBuffer) { delete m_pBuffer; m_pBuffer = NULL; } } … private: char *m_pBuffer; }; A a1; … A a2 = a1; new, new[]和delete,delete[]解析 从几行代码开始: 1) char *p = new char[n]; … delete p; //or delete [] p; 2) void *p = NULL; if (xxx) new A[n]; //class A else new B[n]; //class B … delete p; //or delete [] p; 以上两段代码,两种delete方式,有何区别,哪种正确? 你认为不正确的用法会引起什么问题? 或者,两种都有问题? new, new[]和delete,delete[]解析 对于delete对象指针问题,教科书一般这样说,delete将指针当单个对象来删,而delete[]将指针当成对象数组来删(大意)。 所以,我们得出结论,删除对象数组时若不加[] ,将会导致仅删除数组第一个元素,从而导致内存泄露。 对吗? new, new[]和delete,delete[]解析 为什么要设计两种delete语法? 根本原因在于,C++规定删除一个对象时,必须自动调用析构函数(若有),这个责任给了编译器,而非程序员。所以删除一个对象数组,编译器必须保证调用数组每个元素的析构函数。但一个对象指针是不是数组,编译器无法知晓,必须借助于不同的语法来区分。 可以看出,两种语法本质是为了“析构函数”,而不是释放内存。遗漏[]并不必然导致内存泄露。 new, new[]和delete,delete[]解析 编译器如何识别数组个数?无标准规定,编译器自行实现。 VC编译器的实现: 在数组前部添加一个整型长度(4字节),存放数组长度。即,我们在分配对象数组时,返回的地址其实是向后偏移了4字节的。 用delete[]时,编译器会以头部的整型为数组长度,循环调用每个元素的析构函数,然后将指针前移4字节,调用free()释放数组。 由此大家应该可以看出问题,若遗漏了[],某些情况下不是内存泄露那么简单,将引起内存定位错误,程序崩溃。 但事情并非绝对… new, new[]和delete,delete[]解析 new, new[]和delete,delete[]解析 既然两种delete只是为了析构函数,当一个类没有析构函数时,还要使用上述的数组处理方式吗。没错,编译器是聪明的,它不会做不必要的无用功。 当对象不存在析构函数时,delete,delete[]都等价于free(),事实上编译时就是直接转化为free()了。 是否存在析构函数,并不是完全由程序员决定的。同时满足:1)程序员没有显式定义析构函数2)类中成员若有对象类型,这些成员也不存在析构函数。满足这两个条件,编译器将不为此类生成析构函数,delete时也不经过析构函数这一步骤。否则,即使未显式定义,编译器也会自动生成一个。 顺便提一下,构造函数也类似,若编译器判断不需要时,将不生成构造函数。new等同于malloc. new, new[]和delete,delete[]解析 回头看第一页的代码,结论是不是清楚了? 堆栈初步认识 进程初始化时创建,大小固定 默认1M,但可以用编译选项修改 自底向上增长 线程具有独立的堆栈,

您可能关注的文档

文档评论(0)

f8r9t5c + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

版权声明书
用户编号:8000054077000003

1亿VIP精品文档

相关文档