首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为了获得更好的访问性能,将原始指针与其拥有的shared_ptr一起缓存是个好主意吗?

将原始指针与其拥有的shared_ptr一起缓存并不是一个好主意,因为这可能会导致悬挂指针(dangling pointer)和内存泄漏等问题。让我们详细了解一下这个问题及其解决方案。

基础概念

  1. 原始指针(Raw Pointer):原始指针是C++中最基本的指针类型,它直接指向内存地址。使用原始指针需要手动管理内存,容易导致内存泄漏和悬挂指针等问题。
  2. shared_ptrshared_ptr是C++标准库中的智能指针,用于自动管理动态分配的内存。它通过引用计数来跟踪有多少个shared_ptr实例共享同一个对象,当最后一个shared_ptr被销毁时,对象会被自动删除。

为什么不应该缓存原始指针与shared_ptr

  1. 悬挂指针(Dangling Pointer):当你将原始指针与shared_ptr一起缓存时,如果shared_ptr的引用计数变为0并被销毁,原始指针仍然指向已经被释放的内存,这会导致悬挂指针问题。
  2. 内存泄漏(Memory Leak):如果你不小心多次删除同一个对象,可能会导致未定义行为和内存泄漏。

解决方案

为了避免上述问题,你应该尽量避免将原始指针与shared_ptr一起缓存。以下是一些替代方案:

  1. 只使用shared_ptr:如果你需要传递指针,直接传递shared_ptr即可。shared_ptr会自动管理内存,避免悬挂指针和内存泄漏问题。
  2. 只使用shared_ptr:如果你需要传递指针,直接传递shared_ptr即可。shared_ptr会自动管理内存,避免悬挂指针和内存泄漏问题。
  3. 使用weak_ptr:如果你需要在不增加引用计数的情况下访问对象,可以使用weak_ptrweak_ptr不会影响shared_ptr的引用计数,但需要检查对象是否仍然存在。
  4. 使用weak_ptr:如果你需要在不增加引用计数的情况下访问对象,可以使用weak_ptrweak_ptr不会影响shared_ptr的引用计数,但需要检查对象是否仍然存在。

结论

将原始指针与其拥有的shared_ptr一起缓存不是一个好主意,因为这可能导致悬挂指针和内存泄漏等问题。建议只使用shared_ptrweak_ptr来管理内存,以避免这些问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Chapter 4: Smart Pointers

通用的例子是将 std::unique_ptr 作为返回层次结构中对象的工厂函数的返回类型,对于这样一个层次结构,工厂函数通常在堆上分配一个对象,然后返回指向该对象的指针,而工厂函数调用者则负责在使用完对象后...就会对 a 指向对象的引用计数减 1 ,对 b 指向对象的引用计数加 1 ) 引用计数的存在有一些性能影响 std::shared_ptr 的大小是原始指针大小的两倍 引用计数的内存必须是动态分配的...std::shared_ptr - 如果要使用原始指针来构造 std::shared_ptr ,那么最好在 new 之后就将指针传给 std::shared_ptr 的构造函数,然后使用现有的...(WidgetID id); 如果 loadWidget 是一个调用代价较高的函数,一个合理的优化是在内部缓存每次查询的结果,但是每次请求 Widget 都要缓存的话会导致性能问题,因此另一个合理的优化是当...,其中 A 和 C 持有指向 B 的 std::shared_ptr ,如果 B 也想持有对 A 的指针,那么有三种选择 原始指针:如果 A 被销毁了,而 C 通过 B 来访问 A 就会出现解引用悬空指针

1.6K20

被蚂蚁面试官拷打了,基础真的是太重要了...

) 5、数据库和缓存的不一致性问题如何解决(老生常谈了) 6、C++中为什么父类要定义虚析构函数(可能看我不太懂C++,问了个奇怪问题) 7、C++14、17、20新特性有了解吗 8、C++中shared_ptr...具体的步骤是,先删除缓存,再写数据库,休眠一段时间后再次删除缓存。设置缓存过期时间,所有的写操作以数据库为准,只要到达缓存过期时间,则后面的读请求自然会从数据库中读取新值,然后再回填缓存。...,不能与其他智能指针共享对象。...shared_ptr:共享式智能指针,允许多个指针指向同一个对象。...shared_ptr适用于多个指针共享同一个资源的情况,例如多个指针指向同一个动态分配的数组或对象。

19921
  • 【C++】简单实现C++11的三种智能指针

    垃圾回收器不期望程序员手动控制对象的回收, 因此失效对象的回收时间是无法预测的, 程序员只能控制需要使用的生命周期(或者使用with获得一定的手动控制能力), 从而难以预测性能....智能指针则完全由程序员控制 垃圾回收器对于资源的释放有时候有优化, 例如将大批需要释放的资源集中起来一起释放, 这可以提高回收的效率, 智能指针大多只能逐个释放....但是垃圾回收器的分析和执行仍然有很大的代价 垃圾回收器有时候会遇到缓存优化的问题, 而且回收的时间可能会造成停顿, 智能指针在这点上表现更好, 可以实时处理 垃圾回收器一般在单独的线程中执行, 而智能指针的回收在当前线程的析构函数中执行...和weak_ptr都有一个堆储存的计数器来维护计数进行内存回收, 为了编写的方便将其写为一个基类来继承 由于shared_ptr和weak_ptr的计数器是共享的, 有可能被多线程竞争修改, 因此需要有额外的...的简单实现 shared_ptr需要一个间接层处理引用计数的问题, 因此带来了额外的开销, unique_ptr则完全没有额外的空间开销 对于性能不敏感的情况, 最好不要使用原始指针 建议不要对某个对象进行两次以上的

    1.9K20

    使用 C++ 智能指针遇到的坑

    使用 C++ 智能指针遇到的坑 阅读收益 智能指针目的就是代替原始指针,那么问题来了,原始指针都可以用智能指针代替吗?...不能 智能指针 unique_ptr、shared_ptr 和 weak_ptr三个,那么问题来了 一个不能代替全部吗?...对象所有权 在编程语言中,对堆对象的内存管理是一个麻烦又复杂的问题。一不小心就会带来问题(堆上数据通过指针来访问。) C++里多个变量指向同一块内存导致重复释放。...对象的所有权意味着当我们分配一个对象的时候,谁持有这个对象的所有权 ? Guru Questions 1(大师级问题) 既然智指针,能避免内存泄漏问题, 能代替all场景的原始指针吗?..., 为什么发明三个 而不是一个,来一统天下。 unique_ptr 代替全部原始指针吗? 答:不是的,如果使用不当会造成 core 或者 不执行析构函数。 在类的成员,或者函数参数传递。

    2.8K50

    京东面经(含答案)

    当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。 4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。...但它可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象,从而操作资源。...智能指针就是模拟指针动作的类。所有的智能指针都会重载 -> 和 * 操作符。智能指针还有许多其他功能,比较有用的是自动销毁。...DPDK内部实现(这个是因为简历上有写,关于一个高性能数据包处理库) Winpcap:它的一个流程是npf网络组包过滤器首先负责从网络中采集数据包,完成数据的过滤拷贝到内核缓存区,然后调用相应的动态库文件将数据传递到应用层缓冲区...(3)将原始的数据包还原成流保存 减少对数据包的存储,在内核层提供了通用socket环形缓冲,不进入内核协议栈,最后在应用层通过socket链接同时使用mmap技术直接访问socket环状缓冲区 libevent

    90110

    C++常见避坑指南

    空指针并不指向任何有效的内存地址,所以在调用成员函数时会尝试访问一个不存在的内存地址,从而导致程序崩溃。...类的成员函数并不与具体对象绑定,所有的对象共用同一份成员函数体,当程序被编译后,成员函数的地址即已确定,这份共有的成员函数体之所以能够把不同对象的数据区分开来,靠的是隐式传递给成员函数的this指针,成员函数中对成员变量的访问都是转化成...在 "pass-by-value" 中,函数参数会创建一个副本,而在 "pass-by-reference-to-const" 中,函数参数会成为原始对象的一个引用,且为了避免修改原始对象,使用了常量引用...如果多个执行线程在没有同步的情况下访问同一个 shared_ptr 实例,并且这些访问中的任何一个使用了 shared_ptr 的非 const 成员函数,则会发生数据竞争;可以使用shared_ptr...const int* const 表示一个不可修改的指针,既不能修改指针本身,也不能通过指针修改所指向的值。 总之,const默认与其左边结合,当左边没有任何东西则与右边结合。

    55510

    目录1.智能指针的作用2.智能指针的使用3.智能指针的设计和实现

    不能将指针直接赋值给一个智能指针,一个是类,一个是指针。例如std::shared_ptr p4 = new int(1);的写法是错误的 拷贝和赋值。...get函数获取原始指针 注意不要用一个原始指针初始化多个shared_ptr,否则会造成二次释放同一内存 注意避免循环引用,shared_ptr的一个最大的陷阱是循环引用,循环,循环引用会导致堆内存无法正确释放...但当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。...智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。...智能指针就是模拟指针动作的类。所有的智能指针都会重载 -> 和 * 操作符。智能指针还有许多其他功能,比较有用的是自动销毁。

    1.5K30

    智能指针在面试中得重要地位!

    ::shared+ptr 可以通过访问某资源的引用计数来确定是否自己是最后一个指涉及到该资源的。...,即不再有 shared_ptr指涉到该资源,则std::shared_ptr会析构 /** 引用计数带来性能影响: 1,std::shared_ptr的尺寸使裸指针的两倍,其内部包含一个指涉到该资源的裸指针...std::shared_ptr 产生后,原有的 std::shared将不再指涉到其资源,结果是不需要进行任何引用计数操作。...//好处三:性能提升 std::shared_ptr spww(new Widget); //直接使用 new ,除了要为 Widget 进行一次内存分配,还要为与其相关联得控制块再进行一次内存分配...,之后把原来再主类中得数据成员放置到实现类中 //并通过指针间接访问这些数据成员 /** Pimpl 习惯用法: 第1 部分,是声明 个指针型别的数据成员,指涉到 个非完整型别, 第2 部分,是动态分配和回收持有从前在原始类里的那些数据成员的对象

    1K20

    字节一面,轻松通过!

    如果需要在多线程环境下使用,可以通过Collections.synchronizedList方法来获得一个线程安全的List,但这样可能会降低性能。...std::shared_ptr 是 C++11 引入的智能指针,用于管理动态分配的对象。它允许多个指针共享对同一对象的所有权,提供了一种更安全和方便的内存管理方式,避免了内存泄漏和悬空指针的问题。...特点和用法 共享所有权: std::shared_ptr 允许多个智能指针共同拥有同一个对象,并且在最后一个引用被销毁时自动释放所持有的资源。...不要将裸指针和 std::shared_ptr 混合使用,以免发生悬空指针或重复释放的问题。 使用 std::make_shared 来分配动态对象,因为它能更好地管理内存。...当共享同一个资源时,确保在不再需要时及时释放智能指针。 std::shared_ptr 是 C++ 中常用的智能指针之一,可以帮助管理动态分配的资源,避免内存泄漏,并提高代码的安全性和可维护性。

    18110

    STL四种智能指针

    如果ps和vocation是常规指针,则两个指针将指向同一个string对象。这是不能接受的,因为程序将试图删除同一个对象两次,一次是ps过期时,另一次是vocation过期时。...这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本,缺点是浪费空间,所以智能指针都未采用此方案。 (2)建立所有权(ownership)概念。...但是矩阵类的智能指针类设计思想和Point类一样啊,就不能借用吗?答案当然是能,那就是使用模板技术。为了使我们的智能指针适用于更多的基础对象类,我们有必要把智能指针类通过模板来实现。...答案是:在需要访问资源的时候weak_ptr为你生成一个shared_ptr,shared_ptr能够保证在shared_ptr没有被释放之前,其所管理的资源是不会被释放的。...shared_ptr将接管原来归unique_ptr所有的对象。 在满足unique_ptr要求的条件时,也可使用auto_ptr,但unique_ptr是更好的选择。

    2.7K41

    彻底搞懂之C++智能指针

    shared_ptr 采用引用计数的智能指针。 如果你想要将一个原始指针分配给多个所有者(例如,从容器返回了指针副本又想保留原始指针时),请使用该指针。...weak_ptr 结合 shared_ptr 使用的特例智能指针。 weak_ptr 提供对一个或多个 shared_ptr 实例拥有的对象的访问,但不参与引用计数。...所有实例均指向同一个对象,并共享对一个“控制块”(每当新的 shared_ptr 添加、超出范围或重置时增加和减少引用计数)的访问权限。 当引用计数达到零时,控制块将删除内存资源和自身。...因为除了要管理一个裸指针外,还要维护一个引用计数。 因此相比于 unique_ptr, shared_ptr 的内存占用更高 原子操作性能低 考虑到线程安全问题,引用计数的增减必须是原子操作。...对于此种场景,我们尽量使用 std::move,将 shared_ptr 转移给新的对象。因为移动不用增加引用计数,性能比复制更好。 汇总  智能指针能更安全的回收内存,它能防止:   1.

    3.9K10

    C++智能指针

    如此做,指针指针,辅助类对象与被引用对象的关系如下图所示: image.png 辅助类将引用计数与智能指针类指向的对象封装在一起,引用计数记录有多少个智能指针指向同一对象。...目前这个智能指针智能用于管理Point类的基础对象,如果此时定义了个矩阵的基础对象类,那不是还得重新写一个属于矩阵类的智能指针类吗?但是矩阵类的智能指针类设计思想和Point类一样啊,就不能借用吗?...如果ps和vocation是常规指针,则两个指针将指向同一个string对象。这是不能接受的,因为程序将试图删除同一个对象两次,一次是ps过期时,另一次是vocation过期时。...答案是:在需要访问资源的时候weak_ptr为你生成一个shared_ptr,shared_ptr能够保证在shared_ptr没有被释放之前,其所管理的资源是不会被释放的。...shared_ptr将接管原来归unique_ptr所有的对象。 在满足unique_ptr要求的条件时,也可使用auto_ptr,但unique_ptr是更好的选择。

    3.5K30

    【Example】C++ 标准库智能指针 unique_ptr 与 shared_ptr

    --Microsoft Docs 为了支持对 RAII 原则的简单采用,C++ 标准库提供了三种智能指针类型: std::unique_ptr std::shared_ptr std::weak_ptr...该指针最常用的情况是单例模式和编译防火墙的封装。 如果非要抬杠,使用 get() 函数获取到裸指针给另外一个裸指针,那么你使用智能指针的意义又何在呢?...因此 shared_ptr 是最常用的智能指针,也是最容易出问题的智能指针。 使用它时应当注意: 1,不要将已存在裸指针交由 shared_ptr,任何形式的智能指针都不应该去托管已有的裸指针。...所以,weak_ptr 的作用就是作为一个 "观察者" 访问 shared_ptr 本身,而不是 shared_ptr 所托管的资源。...此函数的速度更快,导致内存碎片更少,但在一次分配时不存在异常,而不是在另一种分配上。 通过使引用对象和更新智能指针中的引用计数的代码具有的更好的地址来提高性能。

    1.1K20

    第 12 章 动态内存

    为了更容易和安全地使用动态内存,新标准库提供了智能指针类型来管理动态对象。 shared_ptr,允许多个指针指向同一个对象。 unique_ptr,“独占”所指向的对象。...也可以将智能指针绑定到一个指向其他类型的资源的指针上,但是我们必须提供自己的操作来代替 delete。 轻易不要使用一个内置指针来访问一个智能指针所负责的对象,因为我们无法知道对象何时会被销毁。...int j = *x; // 错误, x是一个空悬指针 get用来将指针的访问权限传递给代码,只有在确定代码不会 delete指针的情况下,才能使用 get。...,当一个应用需要可变数量的对象时,应该使用标准库容器而不是动态分配的数组,使用容器更为简单、更不容易出现内存管理错误并且可能有着更好的性能。...,用这个指针来访问元素 new将内存分配和对象构造组合在了一起,delete将对象析构和内存释放组合在了一起。

    1.4K40

    《C++Primer》第十二章 动态内存

    如果智能指针释放了其对象,那么返回的指针所指向的对象也就消失了 swap(p, q):交换p和q中的指针 p.swap(q):同上 shared_ptr独有的操作: make_shared(...比如b1和b2是两个StrBlob对象,如果此vector保存在b2中,那么当b2离开作用域时此vector也会被销毁。为了保证此vector中的元素继续存在,我们将vector保存在动态内存中。...虽然编译器不会报错,但是将另一个智能指针也绑定到get返回的指针上是错误的。...2.4 智能指针和异常 为了确保使用异常处理的程序能在异常发生后资源能被正确地释放,一个简单的确保资源被释放的方法是使用智能指针。...当一个应用需要可变数量的对象时,我们更推荐使用vector或其他标准库容器。 大多数应用应该使用标准库而不是动态分配的数组。使用容器更为简单,更不容易出现内存管理错误并且可能有更好的性能。

    1.4K10

    智能指针-使用、避坑和实现

    weak_ptr weak_ptr的出现,主要是为了解决shared_ptr的循环引用,其主要是与shared_ptr一起来使用。...unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联的原始指针。具有->和*运算符重载符,因此它可以像普通指针一样使用。...shared_ptr为了支持跨线程访问,其内部有一个引用计数(线程安全),用来记录当前使用该资源的shared_ptr个数,在结束使用的时候,引用计数为-1,当引用计数为0时,会自动释放其关联的资源。...,如果返回为0或者false,则表示关联的资源不存在 使用lock()成员函数获得一个可用的shared_ptr对象,进而操作资源 当expired()为true的时候,lock()函数将返回一个空的shared_ptr...但是,因为智能指针本身也有其局限性,如果使用不当,会造成意想不到的后果,所以,在使用之前,需要做一些必要的检查,为了更好地用好智能指针,建议看下源码实现,还是比较简单的。

    97310

    4.2 C++ Boost 内存池管理库

    在程序中,动态分配和释放内存是很常见的操作,但频繁的内存分配和释放会导致开销很大,影响程序性能。...boost::pool针对这个问题提供了一个解决方案,它可以预分配并缓存一定数量的内存块,通过重复利用这些内存块来减小内存分配释放的开销,提高程序性能。...boost::shared_ptr是Boost库中的一个智能指针,用于自动管理动态分配的内存。...使用make_shared我们可以将对象的构造和内存分配合并在一起,避免了常规构造函数和动态内存分配的性能损失和代码冗余。...如下代码所示,我们使用shared_ptr封装接口,让impl类不再返回原始指针,而是返回shared_ptr包装的智能指针,这样就可以很好的保护资源。

    91740

    【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针

    在bar函数中,我们将指针ptr传递给了另外一个函数other_fn,我们无法确定other_fn有没有释放ptr内存,如果被释放了,那ptr将成为一个悬空指针,bar在后续还继续访问它,会引发未定义行为...乐于分享的shared_ptrshared_ptr是C++11提供的另外一种常见的智能指针,与unique_ptr独占对象方式不同,shared_ptr是一种共享式智能指针,允许多个shared_ptr...为了避免循环引用,可以将其中一个指针改为 weak_ptr 类型。weak_ptr也是一种智能指针,通常配合shared_ptr一起使用。...我们可以通过weak_ptr的lock()方法来获得一个指向共享对象的shared_ptr。如果weak_ptr已经失效,lock()方法将返回一个空的shared_ptr。...#### 避免一个原始指针初始化多个`shared_ptr````cppint* p = new int(10);std::shared_ptr ptr1(p);// error: 两个shared_ptr

    43600

    C++智能指针的用法

    用法 3.1 std::shared_ptr:共享指针 std::shared_ptr 是 C++ 标准库中的一个智能指针,用于管理动态分配的对象的生命周期。...std::make_shared 是一个创建 std::shared_ptr 的便捷函数,它分配内存并返回一个智能指针。...访问共享的对象:通过解引用 std::shared_ptr,你可以访问共享对象的值,就像使用原始指针一样。...我们访问了这两个智能指针,然后释放了一个智能指针的资源。最后检查了引用计数以验证资源的释放。这个示例展示了 std::shared_ptr 如何自动管理资源,确保资源在不再需要时被正确释放。...访问唯一的对象:可以像使用原始指针一样解引用 std::unique_ptr,以访问唯一的对象。 int value = *anotherUniqueInt; 5.

    14210
    领券