C++11中引入了智能指针来帮助管理动态内存,在一定程度上缓解了悬垂指针问题,但并没有从根本上消除它。 C++自C++11以来引入了智能指针,提供了自动内存管理的能力,这在一定程度上减少了内存泄漏和悬垂指针等问题的发生。然而,即使使用智能指针,C++仍然存在一些潜在的坑。 std::cout << "C++ 悬垂指针示例开始运行..." << std::endl; 7 8 int* rawPtr = nullptr; 9 10 {11 std: 智能指针是行为类似于普通指针的类模板,但提供了额外的功能,如自动内存管理。C++11引入了三种主要的智能指针:unique_ptr、shared_ptr和weak_ptr。 ("智能指针管理的值: {}", smart_ptr);11 12 println!
先理解几个概念1.1 指针:一个内存地址C++ 指针可以简单理解为“某个对象所在的地址”。 前端类比:指针有点像对象引用,但更底层。JS 引用由 GC 管理,C++ 指针经常需要开发者自己保证“它指向的对象还活着”。 1.3 悬垂指针对象生命周期已经结束,但仍有指针指向原来的内存地址,这类指针更正式地称为悬垂指针(dangling pointer),也常被口语化地称为野指针。 所以,C++ 悬垂指针问题天然可能是“概率性”的。2. 总结C++ 悬垂指针问题之所以难,是因为它不一定稳定复现。但不稳定不代表没问题。只要满足:对象已经销毁仍有地方保存它的地址未来可能继续访问这个地址这就是确定的代码风险。
C成也指针,败也指针。确实,指针给程序员提供了很多便利和灵活性,但是不当的指针使用也会造成很多问题。 为了带来指针更好的使用体验,C++中引入了智能指针的概念,其实质就是将指针的一些操作封装成类,程序员通过使用熟悉的指针运算符(-> 和 *)访问封装指针,该指针类通过运算符重载返回封装的原始指针。 C++11中主要有两种类型的智能指针: (1) shared_ptr代表的是“共享所有权”(shared ownership)的指针。 foreach是C++11的新特性,貌似Visual Studio2010中是不支持的,但是2013中是支持的: // print all elements for (vector<shared_ptr 智能指针的使用和普通指针类似,但是需要记住智能指针不能使用delete关键字显示释放空间。
上边的SmartPtr还不能将其称为智能指针,因为它还不具有指针的行为。 指针可以解引用,也可以通过->去访问所指空间中的内容,因此:AutoPtr模板类中还得需要将 、->重载下,才可让其像指针一样去使用*。 只声明不实现+声明成私有 UniquePtr(UniquePtr<T> const &); UniquePtr & operator=(UniquePtr<T> const &); // C++11 UniquePtr & operator=(UniquePtr<T> const &) = delete; private: T * _ptr; }; 3.5 std::shared_ptr C++11 需要注意的是shared_ptr的线程安全分为两方面: 智能指针对象中引用计数是多个智能指针对象共享的,两个线程中智能指针的引用计数同时++或–,这个操作不是原子的,引用计数原来是1,++了两次,可能还是
return _ptr[pos]; } private: T* _ptr; }; unique_ptr 头文件是《memory》 unique_ptr的使用 unique_ptr是C++11 C++98的方式是将拷贝构造函数和拷贝赋值函数声明为私有;C++11的方式就直接在这两个函数后面加上=delete,防止外部进行调用: template<class T> class unique_ptr weak_ptr weak_ptr的使用 weak_ptr是C++11中引入的智能指针,weak_ptr不是用来管理资源的释放的,它主要是用来解决shared_ptr的循环引用问题的。 与boost中智能指针的关系 C++11和boost中智能指针的关系 C++98中产生了第一个智能指针auto_ptr。 C++11,引入了boost中的unique_ptr、shared_ptr和weak_ptr。
智能指针家族包括auto_ptr(C++98)、unique_ptr、shared_ptr和weak_ptr(C++11)等类型。 • unique_ptr是C++11引入的智能指针,其名称意为"唯一指针"。特点是禁止拷贝操作(拷贝构造函数和赋值运算符被删除),仅支持移动语义(通过std::move转移所有权)。 这意味着必须显式构造智能指针 //shared_ptr<Date> sp5 = new Date(2024, 9, 11); //unique_ptr<Date> sp6 = new Date(2024 , 9, 11); 运行结果: 4. C++11和boost中智能指针的关系 • Boost库作为C++标准库的重要补充,是一个由全球C++开发者共同维护的开源项目。
导语: C++指针的内存管理相信是大部分C++入门程序员的梦魇,受到Boost的启发,C++11标准推出了智能指针,让我们从指针的内存管理中释放出来,几乎消灭所有new和delete。 ,可以用p1->get判空做保护 因此在C++11又推出了unique_ptr、shared_ptr、weak_ptr三种智能指针,慢慢取代auto_ptr。 真正的智能指针:shared_ptr auto_ptr和unique_ptr都有或多或少的缺陷,因此C++11还推出了shared_ptr,这也是目前工程内使用最多最广泛的智能指针,他使用引用计数(感觉有参考 多线程安全 本章所说的线程安全有两种情况: 多个线程操作多个不同的shared_ptr对象 C++11中声明了shared_ptr的计数操作具有原子性,不管是赋值导致计数增加还是释放导致计数减少,都是原子性的 多个线程操作同一个shared_ptr对象 同样的道理,既然C++11只负责sp_counted_base的原子性,那么shared_ptr本身就没有保证线程安全了,加入两个线程同时访问同一个shared_ptr
前言 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其中后三个是C++11支持,并且第一个已经被C++11弃用。 C++11智能指针介绍 智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。 C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1,当过期时引用计数减一。 只有引用计数为0时,智能指针才会自动释放引用的内存资源。对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。 所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。 auto_ptr (C++98的方案,C++11已经抛弃)采用所有权模式。
智能指针的由来 在远古时代,C++发明了指针这把双刃剑,既可以让程序员精确地控制堆上每一块内存,也让程序更容易发生crash,大大增加了使用指针的技术门槛。 ,可以用p1->get判空做保护 因此在C++11又推出了unique_ptr、shared_ptr、weak_ptr三种智能指针,慢慢取代auto_ptr。 真正的智能指针:shared_ptr auto_ptr和unique_ptr都有或多或少的缺陷,因此C++11还推出了shared_ptr,这也是目前工程内使用最多最广泛的智能指针,他使用引用计数(感觉有参考 多线程安全 本章所说的线程安全有两种情况: 多个线程操作多个不同的shared_ptr对象 C++11中声明了shared_ptr的计数操作具有原子性,不管是赋值导致计数增加还是释放导致计数减少,都是原子性的 多个线程操作同一个shared_ptr对象 同样的道理,既然C++11只负责sp_counted_base的原子性,那么shared_ptr本身就没有保证线程安全了,加入两个线程同时访问同一个shared_ptr
所有权系统 - 防止悬垂指针 4. 借用检查器 - 防止数据竞争 5. 生命周期系统 - 防止悬垂引用 6. RAII 机制 - 自动资源管理 7. 智能指针 - 安全的共享所有权 8. 项目概述 1.1 项目目标 本项目通过13 个实际演示,全面展示 Rust 的内存安全特性: ✅ 所有权系统防止悬垂指针 ✅ 借用检查器防止数据竞争 ✅ 生命周期系统防止悬垂引用 ✅ RAII 机制防止内存泄漏 内存安全问题概览 2.1 常见的内存安全问题 问题类型 描述 危害 其他语言 悬垂指针 指向已释放内存的指针 程序崩溃、安全漏洞 C/C++ 常见 双重释放 释放同一块内存两次 程序崩溃、内存损坏 C/ 悬垂指针问题 C/C++ 代码(危险): // ❌ C:可能出现悬垂指针 char* create_string() { char str[] = "临时数据"; return str; // 悬垂指针!
什么是智能指针 简单地说,智能指针是用对象去管理一个资源指针,同时用一个计数器计算引用当前指针对象的个数,当管理指针的对象增加或减少时,计数器也相应加1或减1,当最后一个指针管理对象销毁时,计数器为1, 此时在销毁指针管理对象的同时,也对指针管理对象所管理的指针进行delete操作。 下面我们介绍两个常用的智能指针std::shared_ptr和std::weak_ptr。 与std::shared_ptr最大的差别是在赋值的时候,不会引起智能指针计数增加。 智能指针小结 可以看出,智能指针其实是std::shared_ptr和std::unique_ptr, std::shared_ptr可以有多个引用对象,但不能互相引用,而std::unique_ptr
为什么会有智能指针??? C++程序员在编写代码的过程往往都会涉及到堆内存的开辟和释放,使用new和delete关键字。 这无疑要求C++程序员对于对内存的使用要求之高,而智能指针的诞生解放了C++程序员对于堆内存的管理。 智能指针 智能指针是一个类,它将裸指针(带*的指针)进行了封装,实现的指针的自动释放,它的高明之处就在于程序员只需要一次性的设计出一个具有良好功能的智能指针类,用它实例化出来的对象会自动对对象内存的堆资源进行管理 使用智能指针的前提是利用了当栈对象的生存周期结束时,会自动调用析构函数,来进行对对象的销毁。RAII技术。智能指针不能再堆上创建。 设计智能指针的类模板 需要解决的问题: (1)指针可以做的事情,智能指针也必须可以做。需要对*,->运算符进行重载。 (2)*运算符需返回引用,因为*可以连续使用。
那我就接着做下一道题号,第11题号。 ? 什么是双指针,我仔细在脑海中回忆了下。哈哈,原谅我这么健忘。 ……(这是关于指针的解释) 哦原来如此。 想知道什么是双指针,待会文章结尾处会放出视频给你们欣赏下——坐标x轴下面的两个箭头就是双指针。 话不多说,我们就解决11题号(盛最多的水)吧。 ? 两种方法——暴力解决法和双指针法。 双指针法,按官方解释: 将指向较长线段的指针向内侧移动,矩形区域的面积将受限于较短的线段而不会获得任何增加。 但是,在同样的条件下,移动指向较短线段的指针尽管造成了矩形宽度的减小,但却可能会有助于面积的增大。因为移动较短线段的指针会得到一条相对较长的线段,这可以克服由宽度减小而引起的面积减小。 最后使用双指针法去解决的视频供出来,请欣赏!
C++11提供了智能指针,使用智能指针后不需要用户自己释放内存空间,一旦使用时对象超出了自己的生命周期,就会进行自动释放,从而有效解决了内存泄露的问题。 如果函数要返回this指针时,不要将this当做智能共享指针进行返回。因为如果使用同一个指针(this)构造了两个对象,析构时可能导致重复析构。 2 独占的智能指针:std::unique_ptr 独占智能指针使用时有限制,如:不允许其它智能指针共享其内部指针;不允许通过赋值将一个独占指针给另外一个独占指针。 如果想要将一个独占指针分配给另外一个独占指针,有两种方法,分别是: 通过函数返回值; 通过std::move方法转义指针对象的所有权. 代码如下所示: std::unique_ptr<T> p(new T); std::unique_ptr<T> p1 = std::move(p); 在C++ 11中,并没有提供make_unique
很多人谈到c++,说它特别难,可能有一部分就是因为c++的内存管理吧,不像java那样有虚拟机动态的管理内存,在程序运行过程中可能就会出现内存泄漏,然而这种问题其实都可以通过c++11引入的智能指针来解决 c++11引入了三种智能指针: std::shared_ptr std::weak_ptr std::unique_ptr shared_ptr shared_ptr使用了引用计数,每一个shared_ptr main() { auto ptr = std::unique_ptr(new A); auto tptr = std::make_unique(); // error, c++11 关于c++11的智能指针的使用就介绍到这里,大家有问题可以点此留言 ,我会尽快回复~ 参考资料 https://www.jianshu.com/p/b6ac02d406a0 https://juejin.im /post/5dcaa857e51d457f7675360b#heading-16 《深入应用c++11:代码优化与工程级应用》
正因为 std::auto_ptr 的设计存在如此重大缺陷,C++11 标准在充分借鉴和吸收了 boost 库中智能指针的设计思想,引入了三种类型的智能指针,即 std::unique_ptr、std: boost 还有 scoped_ptr,C++11 并没有全部照搬,而是选择了三个最实用的指针类型。 在 C++11 中可以通过 std::unique_ptr 达到与 boost::scoped_ptr 一样的效果。 令很多人对 C++11 规范不满的地方是,C++11 新增了 std::make_shared() 方法创建一个 std::shared_ptr 对象,却没有提供相应的 std::make_unique 当然,在 C++11 中你很容易实现出这样一个方法来: template<typename T, typename...
4、智能指针 智能指针是由于在有指针成员的类中,指针所指向的对象是共享的,防止出现悬垂指针而提出的一种管理指针的办法。 ->ip; 7 } 8 int getValue() { 9 return val; 10 } 11 12 void setPtr(int *p) 再看,可能出现悬垂指针的情况: int *ip = new int(42); HasPtr ptr(ip, 10); delete ip; ptr.set_ptr_val(0); //Disaster! 这里ip和ptr中的指针指向了同一对象,删除了该对象时,ptr中的指针不再指向有效对象,但是你又不知道该对象不在了,所以,这样就出现了悬垂指针。 所以,定义智能指针能有效地解决这个问题,为了避免多个指针共享一个对象时撤销出现的悬垂指针问题,定义智能指针类的主要功能就是来保证在撤销指向对象的最后一个指针时才删除该对象。
这样的类具有指针的所有缺陷,如悬垂指针、内存泄漏等,但无需特殊的复制控制。 缺点:容易导致悬垂指针和内存泄漏问题。 智能指针通过引用计数来防止悬垂指针的出现。当智能指针的引用计数降为0时,它会自动删除所指向的对象。 ,避免了悬垂指针和内存泄漏问题。 使用智能指针替代原始指针:std::unique_ptr和std::shared_ptr是C++11引入的智能指针类型,它们分别提供了独占所有权和共享所有权的管理方式。
这种自由虽带来高性能,但也容易埋下内存泄漏、悬垂指针等隐患。 4.2 悬垂指针指针指向的内存已被释放:cpp复制编辑int* p = new int(5);delete p;*p = 10; // 未定义行为4.3 野指针指针未初始化,指向未知地址:cpp复制编辑 七、现代 C++ 的智能指针C++11 引入智能指针机制,自动管理动态内存,防止内存泄漏与悬垂指针。7.1 std::unique_ptr独占所有权,不能拷贝,只能移动。 delete 后赋为 nullptr 避免裸指针,尽量使用智能指针 多用 RAII 模式封装资源管理 十一、性能优化与策略 内存复用:重复使用大块内存减少频繁分配。 回顾重点: 栈 vs 堆 vs 静态区的分配区别 new/delete 与构造析构的配对使用 常见错误:悬垂指针、内存泄漏、越界访问 智能指针(unique_ptr、shared_ptr)的使用
接雨水(双指针、单调栈) LeetCode 84. 柱状图中最大的矩形(单调递增栈) 两个指针 i, j 分别指向首尾,水的面积 s s = \left ( j-i \right )*min(hi,hj) s=(j−i)∗min(hi,hj) 如果哪边的 h 小,那边的指针向中间移动