C++进阶学习——内存管理

一篇大佬写的超级详细的C++内存管理的教学,链接: https://blog.csdn.net/caogenwangbaoqiang/article/details/79788368
整理笔记备忘。

1 内存管理

1.1 内存分配方式

 栈、堆、自由存储区、静态/全局存储区、常量存储区

  1. 栈:由编译器维护,用于存放局部变量
  2. 堆:由程序员自行维护,对应的操作是new()和delete()
  3. 自由存储区:存放由malloc()/free()管理的内存
  4. 静态/全局存储区:静态变量static和全局变量存放的位置
  5. 常量存储区:只存放常量的内存空间

1.2 栈和堆的区别

空间小(1M左右) 空间大(4G)
由编译器维护 由程序员自行维护
有专用的寄存器和指令,分配效率高 由C/C++函数库实现,有复杂的空间分配算法,分配效率低
不易产生内存碎片(栈结构) 频繁地new和delete会导致大量的内存碎片,程序执行效率会下降
内存地址由高地址向低地址生长(先进后出) 内存由低地址向高地址生长
静态/动态分配(alloc) 动态分配

1.3 使用内存时要注意

  1. 对于分配的内存,要校验是否分配成功
  2. 对分配成功的内存要赋初值
  3. 使用时要防止越界,做边界检查
  4. 动态内存操作必须配对,new/delete,malloc/free
  5. 释放了的内存不能继续使用
    (1) 指针指向的内存释放之后,指针没有置为NULL,会变成野指针
    (2) 在return返回值时避免返回局部变量的指针或引用,因为局部变量在该函数执行完成之后就会被释放

1.4 指针和数组的对比

  1. 内容修改的区别
     数组“对应”着一段内存空间,其内容可以通过对数组的操作进行自由修改
     指针“指向”一段内存空间,指针本质是变量,保存着所指向的数据的地址,指针指向的数据能否修改,取决于这个数据的类型,如果是常量则不可修改,这种错误编译器检查不出来,但实际运行时会出错
  2. 内容复制和比较
     数组复制不能用a=b,需要用strcpy()函数,数组的比较也要使用strcmp()函数
     指针复制可以用p=q,但不是将数据复制,而是将q指向的数据存放的地址拷贝给p,如果修改这个数据,则*p,*q的值都会发生变化,如果想将数据进行拷贝,可以用malloc函数为p申请一块大小为sizeof(T)(strlen(*q)+1)的内存,再通过strcpy函数拷贝,比较大小也是要用到strcmp函数
     sizeof(数组),得到的是数组内数据的长度(字节)
     sizeof(指针),得到的是该指针的类型的长度
    注意,当数组作为函数的参数传递时,会自动退化为同类型的指针,此时sizeof函数无法得到这个数组的大小

1.5 指针参数传递内存

  如果指针作为一个函数的参数,在这个函数内为指针申请内存是不会改变源指针的,因为编译器会为函数的参数创建副本_p,申请内存只会使_p得到一段内存(实际上这块内存在使用之后并没有销毁,也就是产生了内存泄露)
  如果想要在函数里为指针申请内存,就需要传入指向指针的指针&p,或者使用函数返回值来传递p,但参见上文,不能将指向栈空间的指针作为返回值传递,需要使用new或malloc申请内存

1.6 野指针

  野指针是指向“无用的”数据的指针,野指针产生的情况可能有:

  1. 指针没有初始化,创建指针变量的时候一定要赋值
  2. 在delete或free释放指针指向的内存空间后,没有将指针置为NULL
  3. 指针指向的内容生命周期结束,而指针本身还在使用,此时的指针也会变成野指针

1.7 malloc/free和new/delete的区别

  1. malloc/free是标准库函数,new/delete是运算符
  2. C程序只能用malloc/free管理动态内存
  3. 非内部数据类型的对象,new/delete执行时会调用其构造函数和析构函数,而内部数据类型不存在构造和析构函数。
  4. 其实new和delete的底层还是malloc和free

1.8 内存耗尽

 当new/malloc函数返回一个空指针时表示无法申请一段指定大小的内存,此时需要使用return终止该函数或exit(1)终止整个程序
 32位以上的系统基本不存在内存耗尽的情况(因为虚拟内存技术,当内存不够用时,调用硬盘空间作为虚拟内存),但还是要在申请内存时检查申请是否成功

1.9 new/delete使用注意事项

 使用new时会自动调用类的构造函数进行初始化,当构造函数不唯一时,new也支持通过参数类型和数量执行所需的构造函数,如

Obj *obj=new Obj;
Obj *obj=new Obj(参数列表);

注意在new一个Obj[]类型的对象时无法指定参数,只能调用默认的无参数构造函数,在之后要释放该对象时,要同样调用delete[]而不是delete

Obj *obj=new Obj[length];
delete []obj
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Cocos2d-x实战:C++卷》[1] 系统论述了Cocos2d-x游戏开发理论与实践。全书内容涵盖了Cocos2d-x的核心类、瓦片地图、物理引擎、音乐音效、数据持久化、网络通信、数据交换格式、内存管理、性能优化、平台移植、程序代码管理、三大应用商店发布产品等。本书共29章,按内容结构可分为六篇: 第一篇开发基础,即第2章~第8章,内容包括Cocos2d-x简介、环境搭建、字符串、标签、菜单、精灵、场景、层、动作、特效、动画和Cocos2d-x用户事件。 第二篇开发进阶,即第9章~第12章,内容包括游戏音乐与音效、粒子系统、瓦片地图和物理引擎。 第三篇数据与网络,即第13章~第17章,内容包括Cocos2d-x中使用的数据容器类、数据持久化、数据交换格式、基于HTTP网络通信和基于Node.js的Socket.IO网络通信。 第四篇设计与优化,即第18章~第20章,内容包括Cocos2d-x中的常用设计模式、Cocos2d-x中的内存管理和性能优化。 第五篇平台移植,即第21章~第23章,内容包括从Win32到Android平台的移植、从Win32到WindowsPhone8平台的移植和从Win32到iOS平台的移植。 第六篇开发实战,即第24章~第29章,内容包括使用Git管理程序代码和多个项目实战——迷失航线手机游戏项目开发、为迷失航线游戏添加广告、发布放到Googleplay应用商店、发布放到WindowsPhone应用商店和发布放到苹果AppStore。
【资源说明】 基于C++和POLL的服务端和客户端源码(含项目说明+详细注释).zip LINUX网络编程部分开源项目学习和改进 ## 一、基于C++和POLL的服务端和客户端   1)文献来源:《Linux高性能服务器编程》——游双著;\   2)参考学习:https://blog.csdn.net/liuxuejiang158blog/article/details/12503269 \   3)使用说明:终端输入./server ip port即可运行服务端;终端输入./client ip port即可运行客户端;\   4)项目说明:服务端采用POLL形式监控监听和各客户端的连接,分配较大的用户数据数组实现随机访问提高时间利用率;客户端采用管道通信实现与终端的连接建立,也通过POLL实现端口监管。 ## 二、信号集处理——基于C++ EPOLL和信号集的事件处理   1)运用socketpair建立全双工管道,通过EPOLL下的ET模式实现信号的快速接入和管道发送,主循环通过EPOLL实现管道的接受和监听以及发送消息;\   2)文献来源:《Linux高性能服务器编程》——游双著;通过C++进行了程序改写。 ## 三、基于多进程的共享内存   1)运用多进程实现每个子进程专门管理当前的socket链接,主线程负责监听以及管道;\   2)文献来源:《Linux高性能服务器编程》——游双著。 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值