当前位置: 首页 > news >正文

家用电脑可以做网站服务器/抖音营销软件

家用电脑可以做网站服务器,抖音营销软件,东莞seo网络推广专,劳务工程信息平台工作中最常用的编程语言是python和C,通常是完成一个算法原型开发,再交由负责工程优化的同学来进行优化、集成。因此平时代码中很少注意编程规范、内存泄漏、高性能编程等问题。本来C基础就很不扎实,平时使用少了就更生疏了。最近被同事提醒&a…

工作中最常用的编程语言是python和C++,通常是完成一个算法原型开发,再交由负责工程优化的同学来进行优化、集成。因此平时代码中很少注意编程规范、内存泄漏、高性能编程等问题。本来C++基础就很不扎实,平时使用少了就更生疏了。最近被同事提醒,new出来的指针一定要delete,或者使用智能指针,否则会造成内存泄漏。所以在培养写技术blog习惯的开头,就从智能指针谈起。

以下内容是对一些书籍、技术博客的知识点整合。所有参考资料链接附在文章末尾。

什么是内存泄漏

内存泄漏指的是程序未能释放一块不再使用的内存,也就是说程序分配某段内存后,但在释放该段内存之前就失去了对该段内存的控制,造成了内存的浪费。程序不断分配新内存但不再使用的内存没有被释放,最终造成内存用尽。


new/delete

在写程序时,有时会有动态分配内存的需求,在C++中通常使用new/delete来上动态分配一段内存

怎么理解“动态内存分配“呢?与之对应的是静态内存分配。

  • 静态内存分配:编译器在编译的时候就知道所需的内存空间。

  • 动态内存分配:只有在程序运行时才能确定所需空间,编译器无法在编译时预定存储空间

malloc/free和new/delete的区别

  • 它们都是管理动态内存的方式。

  • malloc/free只是分配和释放内存空间,而new/delete除了分配空间外,还会调用构造函数和析构函数。

  • malloc需要手动指定所分配的空间字节数并返回(void*),new/delete根据元素个数自动计算字节数,返回对应类型的指针

  • malloc/free管理内存失败会返回0,new/delete管理内存失败会抛出异常

  • malloc从堆上分配内存空间,new从自由存储区(free store) 上分配内存。自由存储区是C++基于new操作符的一个抽象概念。而堆是对操作系统而言的,是操作系统维护的一块内存区域。自由存储区是否是堆,取决于new的实现细节(是不同编译器实现不同吗?)。自由存储区不仅可以是堆,也可以改用其他内存在实现自由存储。

426a8039ddedd945e60df3a0e5736bcd.png


怎样会造成内存泄漏?

有以下几种常见情况会造成内存泄漏,根本原因都是new出来的内存没有通过delete合理地释放

f14615ddf502af6cd7061b76146e31c3.png强行内存泄漏-1. new出来的对象没有及时delete:疯狂new,但是这些new出来的内存空间并没有实际使用,最终导致内存耗尽。

int main() {     while(1) {         new int[1000]; }     return 0; }

f14615ddf502af6cd7061b76146e31c3.png强行内存泄漏-2. delete掉一个void*类型的指针,导致没有调用对象的析构函数,析构函数内的相关内存清理都没有被执行。

class Object {private:     char* data;     const int size;     const char id; public:     Object(int sz, char c):size(sz), id(c)    {      data = new char[size];       cout << "Object() " << id << " size = " << size << endl;     }     ~Object()    {         cout << "~Object() " << id << endl;         delete []data;    } };int main() {    Object* a = new Object(10, 'A');//Object*指针指向一个Object对象;    void* b = new Object(20, 'B');//void*指针指向一个Object对象;    delete a; //执行delete,编译器自动调用析构函数;    delete b; //执行delete,编译器不会调用析构函数,导致data占用内存没有得到回收;    return 0;}

delete void* 补充:

delete void* 并不是什么都不干。如果是普通指针char*, short*, int*, long*,是会被正确释放的。如果void* 是一个类类型指针,系统会认为void*指向普通内存空间,不会调用指向对象的析构函数。解决方法:把void*转换为原类型指针,再调用delete
template <typename T>inline void safe_delete_void_ptr(void *&target) {    if (nullptr != target) {        T* temp = static_cast(target);        delete temp;        temp = nullptr;        target = nullptr;    }}int *psample = new int(100);safe_delete_void_ptr<int>(psample);

f14615ddf502af6cd7061b76146e31c3.png强行内存泄漏-3. new创建一个数组指针,回收内存时只调用了delete而没有调用delete[],导致只有数组第一个对象的析构函数被执行,其他对象的内存都没有回收。


智能指针

概念:智能指针主要用于管理动态分配的内存(通常是分配在堆上),它将普通的指针封装为一个栈对象。当栈对象的生命周期结束后,会自动调用该栈对象的析构函数,会在析构函数中释放掉申请的内存。因此智能指针的“智能”之处就在于能够自动正确地释放内存,而不需显示调用delete进行释放,也无需人为考虑该什么时候进行释放。

C++11中支持3种智能指针:unqiue_ptr, shared_ptr, weak_ptr. 这里主要介绍最常用的shared_ptr.

shared_ptr

shared_ptr实现共享式拥有的概念。shared_ptr可以通过new出来的指针进行初始化。多个智能指针可以指向相同的对象,使用计数机制来记录指针指向的内存被多少个智能指针所引用。新增一个引用时,计数+1. 调用release()时,当前智能指针会释放资源的所有权,即引用-1,计数-1. 当计数等于0时才会真正释放堆上(严格来说是自由存储区)的内存。

shared_ptr的简单例子

int main(){    string *s1 = new string("s1");  // 自由存储区上动态分配内存    shared_ptr<string> ps1(s1);  // 初始化智能指针    shared_ptr<string> ps2;    ps2 = ps1;  // 引用+1    cout <endl;     cout<endl;       cout << ps1.unique()<<endl;    //0    string *s3 = new string("s3");    shared_ptr<string> ps3(s3);    cout <endl;       cout << ps3.get() << endl;     //033B2C50    swap(ps1, ps3);                //交换所拥有的对象    cout << (ps1.get())<<endl;     //033B2C50    cout << ps3.get() << endl;     //033AEB48    cout << ps1.use_count()<<endl;   //1    cout <endl;     ps2 = ps1;    cout << ps1.use_count()<<endl;   //2    cout <endl;     ps1.reset();     //放弃ps1的拥有权,引用计数的减少    cout <endl;      cout <endl;  }

weak_ptr

介绍weak_ptr之前,先看看shared_ptr的缺点。如果两个对象都有一个shared_ptr成员变量指向对方,造成循环引用。请看如下例子,退出作用域时,先释放的是pa(后构造的对象先释放)。而pa的引用次数为2,减去1后变为了1,所以pa指向的自由存储区内存没有被释放。但pa这个栈对象已经被销毁了。

接下来释放pb,pb的计数也是2,减1后变为1,pb指向的自由存储区内存也没有被释放。

class B;    //声明class A {public:    shared_ptr pb_;     ~A()    {        cout << "A delete\n";    }};class B {public:    shared_ptr pa_;    ~B()    {        cout << "B delete\n";    }};void fun(){    shared_ptr pb(new B());     shared_ptr pa(new A());     cout << pb.use_count() << endl;  //1    cout << pa.use_count() << endl;  //1    pb->pa_ = pa;    pa->pb_ = pb;    cout << pb.use_count() << endl;  //2    cout << pa.use_count() << endl;  //2}int main() {    fun();    return 0;}

这时候就使用weak_ptr来辅助。把以上例子A或B成员变量类型其中一个shared_ptr改为weak_ptr就可以了。例如把B类中的shared_ptr改为weak_ptr。weak_ptr的构造析构不会影响shared_ptr引用计数的大小,因此下面第7行不会增加pa的引用计数。而在退出函数时,pa首先被析构,计数由1减为0,内存被释放。因为pa被析构了,pb的引用计数就会自动减1,由2变为1。最后再执行pb的析构,计数由1减为0,内存被释放。

void fun(){    shared_ptr pb(new B());     shared_ptr pa(new A());     cout << pb.use_count() << endl;  //1    cout << pa.use_count() << endl;  //1    pb->pa_ = pa;  // 不会增加pa的计数    pa->pb_ = pb;    cout << pb.use_count() << endl;  //2    cout << pa.use_count() << endl;  //1}

42a10aac25d960cdce554443b099e676.png参考资料:

C++——动态内存分配 

https://www.cnblogs.com/southcyy/p/10271981.html

malloc与new分配内存 

https://blog.csdn.net/xijiacun/article/details/53150363

自由存储区与堆 

https://www.cnblogs.com/QG-whz/p/5060894.html

C++造成内存泄漏的原因汇总 

https://blog.csdn.net/qq_18824491/article/details/78902636

如何优雅地释放void* 

https://blog.csdn.net/SweetTool/article/details/77688337

详解C++11智能指针 

https://www.cnblogs.com/WindSun/p/11444429.html

浅谈shared_ptr及shared_ptr涉及到的循环问题

https://blog.csdn.net/qq_34992845/article/details/69218843

http://www.jmfq.cn/news/5221135.html

相关文章:

  • 一朋友做色情网站被抓了/企业营销策划案例
  • 网站做多长时间才会成功/搜索引擎营销的手段包括
  • 网站建设自评报告/聚名网
  • 个人网站有商业内容备案/安新seo优化排名网站
  • 网站建设哪家公司靠谱/新冠疫情最新消息今天公布
  • 有关房地产开发建设的网站/搜索引擎推广培训
  • 住建部关于epc总承包文件/沧州网站推广优化
  • 怎样制作表白网站/网络优化
  • 湖南岳阳网站开发网络公司/链接点击量软件
  • 美食网站建设设计方案/营销策划书格式及范文
  • 个人备案网站可以做商城展示/百度app 浏览器
  • 淮安做网站服务单位/什么网站可以免费发广告
  • wordpress网站代码/牛排seo系统
  • 国家建设部网站证书查询/52种新颖的促销方式
  • .cn域名可以做英文网站吗/品牌宣传策划方案
  • 免费网页游戏在线玩/怎么卸载windows优化大师
  • 本地怎样上传自己做的网站/安庆seo
  • 网络游戏制作软件/天津seo托管
  • 如何在百度做自己公司的网站/营销的方法手段有哪些
  • 东莞市专注网站建设品牌/短视频怎么赚钱
  • 在哪个网站做服装代理批发/seo研究协会网
  • 没有网站如何做adsense/站长工具ping
  • 工信部企业网站备案/成人计算机速成培训班
  • 专做和田玉的网站/0元入驻的电商平台
  • 旅游网站做模板素材/营销软文范例大全100
  • 如何对网站的图片做cdn/制造业中小微企业
  • 网站正在建设中 模板 下载/windows优化大师有什么功能
  • 如何做电子书网站/外链网站大全
  • 网站开发 合作协议/网站策划
  • 网站栏目建设调研/百度怎么做广告推广