【C++】动态内存与智能指针

C++常见的内存分配方式有三种:

  • 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量;
  • 从栈内存分配,这里主要是存储函数内的非static对象;
  • 从堆内存动态分配

其中,静态存储区以及栈内存中的对象,都是由编译器自动创建和销毁,而堆内存中的对象都是由程序显示控制的,通常都是new创建delete销毁或者malloc创建free销毁。动态内存的管理非常棘手,如果动态地创建了对象却没有显式得销毁,就会发生内存泄漏;如果在还有指针引用的时候释放了内存就会出现引用非法内存的指针。

C++11提供了两种智能指针用于管理动态对象,他们可以自动的释放所指向的对象,不用再人为显式地手动销毁,他们都定义在memory头文件中:

  • shared_ptr,允许多个指针指向同一个对象:

    shared_ptr<string> p; //可以指向string的shared_ptr

    shared_ptr支持的操作:

    void sharedPtrTest(){
        //make_shared函数的作用是:
        //    在堆中分配一个对象并初始化它,并返回指向该对象的shared_ptr
        shared_ptr<int> p1 = make_shared<int>(0);
        shared_ptr<int> p2 = make_shared<int>(1);
    
        //在条件判断中使用智能指针,相当于检测它是否为空
        //如果只能指针没有指向任何内容,返回false,否则返回true
        if (p1 && p2){
            //解引用智能指针,用法与普通指针一样,获得它指向的对象
            cout << *p1 << endl;//output:0
    
            //返回p中保存的指针
            cout << p2.get() << endl;//output:002FB464(vs2013)
    
            //交换,也可以写作p1.swap(p2)
            swap(p1, p2);
            cout << *p1 << " " << *p2 << endl; //output: 1 0
        }
    
        //智能指针的拷贝赋值,递增p1的引用计数,此之后p1被引用2次,p2被引用1次
        shared_ptr<int> p3(p1);
    
        //返回p1共享智能指针的数量,即p1指向对象被引用次数
        cout << p1.use_count() << endl; //output: 2
        cout << p2.use_count() << endl; //output: 1
    
        //如果只有自己指向这个对象,返回true,否则false
        cout << p1.unique() << endl; //output: 0,说明 p1不是独占对象的
        cout << p2.unique() << endl; //output: 1,说明p2独占对象
    }

再说说引用计数,每个shared_ptr可以看作有一个关联的计数器,保存着这个指针指向的动态内存内的对象被引用的次数,即有多少个智能指针指向它,当变为0即没有指针指向它时这块内存会被自动释放。而只要还有智能指针指向它,它就不会被释放。

  • unique_ptr,该指针会独占指向的对象,不允许其他指针引用,用法基本与shared_ptr相同,但是由于它是独占对象,所以不能进行拷贝赋值以及引用计数相关操作。

    void uniquePtrTest(){
        unique_ptr<int> p1(new int(42));
    
        //p1.release()返回指向该内存指针,将p1置为空,表示p1放弃控制权
        //此行代码表示p1转移出去对该对象的所有权给p2,即p1置空返回指针赋值给p2
        unique_ptr<int> p2(p1.release());
        cout << *p2 << endl; //output:42
    
        unique_ptr<int> p3(new int(10));
    
        //释放p2原指向对象,将p3置空,其指向的对象赋值给p2,reset()也可以没有参数,那么久只释放p2原有对象,不对其赋新值
        p2.reset(p3.release());
        cout << *p2 << endl; //output:10
    
    }
时间: 2024-12-22 21:32:46

【C++】动态内存与智能指针的相关文章

C++ Primer笔记8_动态内存_智能指针

1.动态内存 C++中,动态内存管理是通过一对运算符完成的:new和delete.C语言中通过malloc与free函数来实现先动态内存的分配与释放.C++中new与delete的实现其实会调用malloc与free. new分配: 分配变量空间: int *a = new int; // 不初始化 int *b = new int(10); //初始化为10 string *str = new string(10, ); 分配数组空间: int *arr = new int[10];//分配的

【足迹C++primer】39、动态内存与智能指针(3)

动态内存与智能指针(3) /** * 功能:动态内存与智能指针 * 时间:2014年7月8日15:33:58 * 作者:cutter_point */ #include<iostream> #include<vector> #include<memory> #include<string> using namespace std; /** 智能指针和异常 */ void f() { shared_ptr<int> sp(new int(42));

【足迹C++primer】39、动态内存与智能指针(2)

动态内存与智能指针(2) 直接管理内存 void fun1() { //此new表达式在自由空间构造一个int型对象,并返回指向该对象的指针 int *pi1=new int; //pi指向一个动态分配.未初始化的无名对象 string *ps3=new string; //初始化为空string int *pi2=new int; //pi指向一个未初始化的int int *pi3=new int(1024); //pi指向的对象的值为1024 string *ps4=new string(1

C++笔记(12):动态内存和智能指针

动态内存和智能指针 动态内存: 1.针对堆里面存放的对象 2.使用new delete运算符 3.智能指针:shared_ptr(多个指针指向同一个对象);  unique_ptr(一个指针指向一个对象);     weak_ptr(弱引用,管理shared_ptr) 4.标准库函数:make_shared<int>()

C++primer第十二章读书笔记---动态内存与智能指针

    目前为止我们使用过的静态内存,栈内存和内存池,静态内存用来保存局部static对象.类static成员,以及定义在任何函数之外的成员.栈内存用来保存定义在函数内部的非static成员,分配在静态 内存或栈内存中的对象由编译器自动创建或销毁,对于栈对象仅在其定义的程序块运行时才有效,static对象在程序运行之前分配,程序结束时销毁.除了静态内存和栈内存外,每个程序还拥有一个内存池(堆)在堆上分配动态对象,当动态对象不再使用时,我们必须显示的销毁它.     (一).动态内存与智能指针  

动态内存1(动态内存与智能指针)

静态内存用来保存局部 static 对象.类 static 数据成员 以及任何定义在函数之外的变量.栈内存用来存储定义在函数内部的非 static 对象.分配在静态或栈内存中的对象由编译器自动创建和销毁.对于栈对象,仅在其定义的程序块运行时才存在:static 对象在使用之前分配,在程序结束时销毁. 除了静态内存和栈内存,每个程序还拥有一个内存池.这部分内存被称作自由空间或堆.程序用堆来存储动态分配的对象--即,那些在程序运行时分配的对象.动态对象的生存周期由程序来控制,即当动态对象不再使用时,

第十二章 动态内存与智能指针

动态内存与智能指针 [智能指针]头文件#include<memory>shared_ptr: 允许多个指针指向同一个对象unique_ptr: "独占"所指向的对象weak_ptr:伴随类,它是一种弱引用,指向shared_ptr所管理的对象. 原文地址:https://www.cnblogs.com/sunbines/p/8552298.html

动态内存——动态内存与智能指针

全局对象在程序启动时分配,在程序结束时销毁.对于局部自动对象,当我们进入其定义所在的程序块时被创建,在离开块时销毁.局部static对象在第一次使用前分配,在程序结束时销毁. 除了自动和static对象外,C++还支持动态分配对象.动态分配的对象的生命期与它们在哪里创建是无关的,只有当显示地被释放时,这些对象才会销毁. 静态内存用来保存局部static对象.类static数据成员以及定义在任何函数之外的变量.栈内存用来保存定义在函数内的非static对象.分配在静态或栈内存中的对象由编译器自动创

动态内存和智能指针

c++中动态内存的管理是通过一对运算符来完成的:new.在动态内存中为对象分配空间并返回一个指向该对象的指针,我们呢,可以选择对对象进行初始化,delete接受一个动态对象的指针,销毁该对象,并返回与之关联的内存. 动态内存的使用的不足: 1.保证在正que的时间释放内存是及其困难 2.有时我们会忘记释放内存,这样就导致内存泄漏 3.有时还存在引用内存的情况,但是我们已经释放了它,这样就导致非法内存的指针 这样就产生了智能指针(smart pointer)来动态管理内存,智能指针优点: 1.行为

12.1 动态内存与智能指针

//练习12.10-11 shared_ptr<int> p(new int(42)); //process(p); //process(shared_ptr<int>(p)); //用p来初始化创建一个临时的智能指针 //也指向p所指向的内存 process(shared_ptr<int>(p.get())); //用p.get()返回的内置指针来初始化创建一个 //临时的智能指针,指向p所指向的内存 //当离开process函数的作用域时,这个临时智能指针会被销毁