在 C/C++ 语言中,内存泄露的问题一直困扰着广大的开发者,因此各类库和工具的一直在努力尝试各种方法去检测和避免内存泄露,如 boost,智能指针技术应运而生。...,而 std::shared_ptr 持有的资源可以在多个 std::shared_ptr 之间共享,每多一个 std::shared_ptr 对资源的引用,资源引用计数将增加 1,每一个指向该资源的...:enable_shared_from_this { public: A() { m_i = 9; //注意: //比较好的做法是在构造函数里面调用.../test_std_enable_shared_from_this_problem A constructor 我们发现在程序的整个生命周期内,只有 A 类构造函数的调用输出,没有 A 类析构函数的调用输出...注意代码中我提醒注意的地方,该段程序会在代码 12 行处崩溃,崩溃原因是调用了 conn->peerAddress() 方法。为什么这个方法的调用可能会引起崩溃?现在可以一目了然地看出了吗?
为什么 unique_ptr 需要明确知道类型的析构函数这个问题是我写 unique_ptr 调试接口的时候才注意到的,之前确实不知道。为什么会这样呢?...默认构造的时候允许是不完整类型。为什么会这样呢?shared_ptr 怎么处理 Deleter 呢?...Deleter 的类型在 control block 的具体类型上,shared_ptr 本身只持有一个 control block 基类的指针,通过虚函数来调用 Deleter。...而因为 shared_ptr 构造的时候要求必须是 complete type,control block已经知道怎么析构了,shared_ptr 析构的时候就调用个虚函数,具体事情它不管的。...我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!
这不,今天是七夕,原本打算和女朋友吃饭、看电影......一气呵成的,结果我的 HttpServer 又崩溃了。 1....的目标要设计成一个可独立使用的 Http 模块,所以在最外层我又建立了一个 HttpServer 类,这个类负责与外部使用方交互,外部使用这个 http 库的时候只要初始化一个 HttpServer...HttpConnection 对象时把 HttpSessionManager 对象的 m_pEventLoop 指针通过 HttpConnection 构造函数传递过来,前者是在 HttpServer...IO 复用函数上,所以下一轮循环时,IO 复用函数检测到 wakeupFd 有读事件,在 wakeupFd 读事件处理函数中执行我们注册的任务(这一技巧广泛地用于各种开源网络库和商业 C++ 产品,建议小伙伴们掌握...m_spEventLoop->registerEvent(m_fd, EventType::Read);,此时 m_spEventLoop 虽然是一个智能指针,但是在 HttpConnection构造时传入的
std::shared_ptr 对资源的引用,资源引用计数将增加 1,每一个指向该资源的 std::shared_ptr 对象析构时,资源引用计数减 1,最后一个 std::shared_ptr 对象析构时...std::shared_ptr 对象,在 getSelf() 中调用 shared_from_this() 即可。...:enable_shared_from_this { public: A() { m_i = 9; //注意: //比较好的做法是在构造函数里面调用...,崩溃原因是调用了 conn->peerAddress() 方法。...为什么这个方法的调用可能会引起崩溃?现在可以一目了然地看出了吗?
先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数。...name指针被分配一次内存,但是程序结束时该内存却被释放了两次,会导致崩溃! 这是由于编译系统在我们没有自己定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行的是浅拷贝!...即对指针name拷贝后会出现两个指针指向同一个内存空间。...再说几句: 当对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情形: 1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现...; 2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。
,在构造时一次。...我能想到的必须用std::shared_ptr的场景有:异步析构,缓存。除此之外想不出任何必须的场景,欢迎小伙伴们在评论区补充。...我曾经在知乎上看到这样一个问题:zhihu.com/question/5523。...在某些条件下,编译器会自动将循环优化为向量化操作: 循环内部访问的是连续内存。 循环内部没有函数调用,没有if分支。 循环之间没有依赖。...我们团队正在基于apache arrow做一些向量化计算的工作,后续也会有文章分享关于向量化优化的详细介绍。 推荐阅读 AI绘画火了!一文看懂背后技术原理 CPU如何与内存交互?
,在构造时一次。...我能想到的必须用 std::shared_ptr 的场景有:异步析构,缓存。除此之外想不出任何必须的场景,欢迎小伙伴们在评论区补充。...我曾经在知乎上看到这样一个问题:https://www.zhihu.com/question/552352098。...在某些条件下,编译器会自动将循环优化为向量化操作: 循环内部访问的是连续内存 循环内部没有函数调用,没有 if 分支 循环之间没有依赖 举个例子,下方的代码非常的向量化不友好: enum Type { ...我们团队正在基于 apache arrow 做一些向量化计算的工作,后续也会有文章分享关于向量化优化的详细介绍。 红包福利 点击回复:1024 即可抽奖红包封面
对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针。...为什么要使用智能指针 智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏。...使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源。...而#2不会留下悬挂的unique_ptr,因为它调用 unique_ptr 的构造函数,该构造函数创建的临时对象在其所有权让给 pu3 后就会被销毁。...C++有一个标准库函数std::move(),让你能够将一个unique_ptr赋给另一个。尽管转移所有权后 还是有可能出现原有指针调用(调用就崩溃)的情况。
return 0; } 多线程下的对象析构问题 在多线程环境下,对象的析构问题需要特别注意,因为多个线程可能同时访问和操作同一个对象。如果多个线程同时尝试析构同一个对象,可能会导致对象被多次删除。...主线程在启动另一个线程后早期销毁了资源,而另一个线程仍在使用已经销毁的资源。这会导致未定义行为,访问无效的内存,可能导致崩溃或数据损坏。...异常安全性:智能指针在异常情况下能够保证资源的正确释放。即使发生异常,智能指针也会在其作用域结束时被销毁,并调用析构函数来释放资源。...std::unique_ptr支持所有权的转移,可以通过move将一个std::unique_ptr实例的所有权转移到另一个实例。这种所有权转移可以通过移动构造函数和移动赋值运算符来实现。...// 创建一个 std::unique_ptr unique_ptr uResource1 = make_unique(); // 使用移动构造函数将所有权转移到另一个
8 16、为什么析构函数必须是虚函数?...为什么C++默认的析构函数不是虚函数 8 17、函数指针 9 18、fork函数 9 19、类构造和析构顺序 9 20、静态函数和虚函数的区别 10 21、静态多态与动态多态 10 22、const修饰普通函数与成员函数的目的...4、重写和重载 5、面向对象编程 (1)封装:将数据或函数集合在一个类中类。 (2)继承:子类可以继承父类的一些数据和函数。 (3)多态:运行时,可以通过指向基类的指针,调用派生类中的方法。...在基类中实现纯虚函数的方法是在函数原型后加“=0” 如:virtual void funtion1()=0 如果A中的virtual去掉以后,以上的结果将会是A的foo 16、为什么析构函数必须是虚函数...为什么C++默认的析构函数不是虚函数 析构函数设置为虚函数可以保证我们new一个子类时,可以使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。
, 也可以像上面代码中使用同一客户端分别发送几次完成后再分别全部接收,框架会分别接收到每一个调用的结果, 到这里就会有一个疑问:同时调用那么多次,如何才能识别返回的消息是那次调用返回呢?...比较简单的做法就是调用过程中加一个序列号的参数,每次调用返回的序列号都相同,而不同次调用的序列号都不同。...的类以供实现异步调用,初步看到是使用回调函数进行的。...此种方法正在研究中,随后会将研究结果补充上来 服务端异步 Thrift服务端异步通过使用TNonblockingServer实现,TNonblockingServer依赖libevent,即编译Thrift...\n"); return 0; } TNonblockingServer也可以不使用线程池,仅仅使用单线程处理,此时只需在构造TNonblockingServer时不添加threadManager
理论上说,base 模块是多个团队都在使用的基础模块,经过长时间的验证,因为代码内部逻辑问题导致的崩溃的可能性较低,但是调用堆栈却显示 libbase.lib 内部崩溃,在崩溃的地方加上断点后,每次第二次执行到这里就必然崩溃...一块内存已经被释放了,但是因为逻辑问题,再次尝试释放这块内存,这个时候也会出现崩溃,再次尝试释放不一定是用户主动行为,可能是编译器偷偷安排的工作,例如析构函数的调用。...于是,我认真检查和阅读了 base 模块的相关代码,确认使用 base 模块进行了正确的初始化,所以崩溃原因不是这个。 4.尝试二 那会不会真的是 base 模块的 bug?...,所以无法在 HttpSession 的初始化列表中调用其拷贝构造函数赋值给 m_spConnection 对象,好在 std::unique_ptr 的移动构造函数(Move Constructor)...哦,还有个地方忘记修改了,在 HttpSession 构造函数中,pConnection 被 std::move 之后就剩下一个空壳子了,其“肉体”已经转移给了 m_spConnection,所以不能在
当然我也知道,我不去一定会后悔,索性还是去尝试未尝不是一件好事,毕竟正好还有小米和滴滴,bigo的现场面试。...我看你写了三个项目,说一个熟悉一些的,背景,你做了啥,有什么难点 面试官:我们看几个简单题 构造函数为什么不能是虚函数 虚函数的调用需要虚函数表指针,而该指针存放在对象的内容空间中;若构造函数声明为虚函数...可以从一个weak_ptr构造一个shared_ptr以取得共享资源的所有权。...当expired() == true的时候,lock()函数将返回一个存储空指针的shared_ptr。...0,则删除对象),并增加右操作数所指对象的引用计数; 调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
动态分配的资源,交给一个类对象去管理,当类对象声明周期结束时,自动调用析构函数释放资源。 1.2 智能指针历史历程 C++ 98 中产生了第一个智能指针auto_ptr。...1.3 为什么需要智能指针 1.3.1 内存泄漏 我们在讲为什么之前先来了解一下什么是内存泄漏。 内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。...2.3 智能指针的拷贝问题 如果我们用一个智能指针拷贝构造一个智能指针,或者用一个智能指针赋值给另一个智能指针。这样的操作都会导致程序崩溃。...析构函数,将管理资源对应的引用计数--,如果为0就需要进行释放。 拷贝构造函数中,与传入对象一起管理资源,将该资源的引用计数++。...可以看到模板参数定制删除器是在构造函数的。
下面一步一步地向大家介绍我自己土制佳酿的垃圾回收系统,可以按照需要自由选用,而不影响其他代码。 构造函数和析构函数 C++中提供的构造函数和析构函数很好的解决了自动释放资源的需求。...因此,我们可以将需要分配的资源在构造函数中申请完成,而在析构函数中释放已经分配的资源,只要对象的生存期结束,对象请求分配的资源即被自动释放。...那么就仅剩下一个问题了,如果对象本身是在自由存储区(Free Store,也就是所谓的“堆”)中动态创建的,并由指针管理(相信你已经知道为什么了),则还是必须通过编码显式的调用析构函数,当然是借助指针的...,因此在函数退出点生存期结束,此时auto_ptr的析构函数调用,自动销毁内部指针维护的string对象(先前在构造函数中通过new表达式分配而来的),并进而执行string的析构函数,释放为实际的字符串动态申请的内存...最后,在整个过程中,除了在使用shared_ptr 的构造函数时使用了new表达式创建新之外,并没有任何删除指针的动作,但是所有的内存管理均正确无误,这就是得益于shared_ptr的精巧的设计。
大家好,又见面了,我是你们的朋友全栈君。...,主要用到了这两点: 智能指针体现在把裸指针进行了面向对象的封装,在构造函数中初始化资源地址,在析构函数中负责释放资源 利用栈上的对象出作用域自动析构这个特点,在智能指针的析构函数中保证释放资源。...就好比SmartPtr* ptr = new SmartPtr();这段代码中,在堆空间定义一个智能指针,这依然需要我们手动进行delete,否则堆空间的对象无法释放,因为堆空间的对象无法利用出作用域自动调用析构函数...,auto_ptr底层先是将ptr1置空,然后将指向的资源再给ptr2, auto_ptr所做的就是使最后一个构造的指针指向资源,以前的指针全都置空,如果再去访问以前的指针就是访问空指针了,这很危险。...t1.detach(); } // 让主线程等待,给时间子线程执行,否则main函数最后会调用exit方法结束进程 std::this_thread::sleep_for(std::chrono:
. // Critical areas above mut.unlock(); } 以上代码展示了一个将字符串写进某个文件描述符的函数,并且这个函数会被很多线程并行调用 (这种情况在高并发线上服务的...并且在复杂的逻辑中,往往很可能会忘了解锁,或者花很多精力来管理锁的获得和释放(如果在一个函数调用中有多处返回,每个return statement之前都需要 unlock)。...其异常安全的保障就是析构函数一定会在对象归属的scope退出时自动被调用(在本例中在函数返回前执行)。...智能指针 接下来笔者将介绍RAII在C++中最强的应用:智能指针。 C++中一个非常常见的应用场景就是调用一个函数来产生一个对象,然后消费这个对象,最后手动释放指针。如以下代码所示。...有人可能会疑惑,为什么 get_object函数创建的 unique_ptr为什么没有在函数返回前释放指针?
这意味着你不能使用拷贝构造函数或拷贝赋值运算符来创建一个 scoped_ptr对象的副本,如果你尝试这样做,编译器将报错 其实scoped_ptr的拷贝构造函数是被声明为private并且是没被定义的...当你使用std::move函数将一个unique_ptr对象转化为右值引用并将其传递给另一个unique_ptr对象来初始化时,就会调用这个构造函数 unique_ptr& operator=(unique_ptr...这就是为什么调用delete mptr;来删除指向的对象 需要注意的是,这段代码并不会调用指向的对象的析构函数。析构函数是在delete mptr;这一行被调用时自动调用的。...这意味着,这些对象不会被删除,它们的析构函数也不会被调用 记住只有当引用计数变为0,指向的对象才会被删除,才会调用析构函数 上面这些话可能有点绕,结合我上面对这个代码的分析,可以理解下 ~CSmartPtr...因此,即使对象p被删除,子线程仍然可以访问它所在的内存地址并调用它的方法 但是,这样的行为是不安全的,因为在删除对象后访问它会导致未定义行为。在这种情况下,程序可能会崩溃或产生意外的结果。
在bar函数中,我们将指针ptr传递给了另外一个函数other_fn,我们无法确定other_fn有没有释放ptr内存,如果被释放了,那ptr将成为一个悬空指针,bar在后续还继续访问它,会引发未定义行为...创建unique_ptr对象我们可以std::unique_ptr的构造函数或std::make_unique函数(C++14支持)来创建一个unique_ptr对象,在超出作用域时,会自动释放所管理的对象内存...std::unique_ptr 对象,指向一个 MyClass 对象 std::unique_ptr ptr(new MyClass); // 调用 reset,将 std...创建shared_ptr对象同样的,C++也提供了std::shared_ptr构造函数和std::make_shared函数来创建std::shared_ptr对象。...: 2wp is expired: 1回到shared_ptr的循环引用问题,利用weak_ptr不会增加shared_ptr的引用计数的特点,我们将Node.next的类型改为weak_ptr, 避免
领取专属 10元无门槛券
手把手带您无忧上云