C++ 智能指针

C++ 智能指针

原始指针

不释放会导致内存泄露。

删除同一指针多次会得到未定义行为(undefined behaviour),意味着可能正常工作,可能崩溃也可能是发生一些随机的事情。

示例:

    int *a;
//    a = new int[256];
    a = new int[512];

    delete[] a;
    delete[] a;

a = new int[256]时,两次delete并不会报错,程序可以正常运行,正常退出;

而当a = new int[512]时,会报double free or corruption (!top)

g++版本:g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

C++98

C++98中使用auto_ptr,模板类型

缺点:

  • 函数调用返回时内存对象并不会返回

    class Stu {
        int age;
        char *name;
    public:
        Stu() : age(0), name(nullptr) {
        }
    
        Stu(int age, const char *name) {
            this->age = age;
            this->name = new char[1024];
            strcpy(this->name, name);
        };
    
        void Show() {
            printf("age:{%d}, name:{%s}\n", this->age, this->name);
        }
    
        ~Stu() {
            puts("destruct...");
            delete[] name;
            name = nullptr;
        }
    };
    
    void Fun(std::auto_ptr<Stu> ptr1) {
        auto p2 = ptr1;
        p2->Show();
    }
    
    int main() {
        std::auto_ptr<Stu> ptr(new Stu(10, "hzh"));
    
        Fun(ptr);
        ptr->Show();
    
        return 0;
    }
    

    在上面的代码中会报段错误

  • 只能用于单个对象,不能用于对象数组

  • 不能与标准容器库中的容器使用,如list, vector等等。

从C++11开始,优先使用unique_ptr

C++11

c++11中使用unique_ptr, shared_ptrweak_ptr

shared_ptr

多个共享指针可以引用同一个对象,当最后一个指针失效后内存自动释放。

实现机制类似引用计数

正常使用

    Stu *stu = new Stu(20, "qwe");
    std::shared_ptr<Stu> ptr(stu);
    auto p2 = ptr;
    auto p3 = p2;

出现问题

    Stu *stu = new Stu(20, "qwe");
    std::shared_ptr<Stu> ptr(stu);
    std::shared_ptr<Stu> ptr2(stu);

缺点:循环引用问题

#include <iostream>
#include <cstring>
#include <memory>
#include <bits/shared_ptr.h>

using namespace std;

class B;

class A {
public:
    A() : m_a(5) {};

    ~A() {
        cout << " A is destroyed" << endl;
    }

    void PrintSpB();

    shared_ptr<B> m_sptrB;
    int m_a;
};

class B {
public:
    B() : m_b(10) {};

    ~B() {
        cout << " B is destroyed" << endl;
    }

    shared_ptr<A> m_sptrA;
    int m_b;
};


int main() {
    shared_ptr<B> sptrB(new B);
    shared_ptr<A> sptrA(new A);
    sptrB->m_sptrA = sptrA;
    sptrA->m_sptrB = sptrB;
}

weak_ptr

weak指针提供共享语义但是不提供拥有语义。它是一个类模板

    std::shared_ptr<Stu> sharedPtr(new Stu(10, "hzh"));
    std::weak_ptr<Stu> weakPtr(sharedPtr);
    printf("%ld\n", weakPtr.use_count());

可以解决循环引用问题

#include <iostream>
#include <cstring>
#include <memory>
#include <bits/shared_ptr.h>

using namespace std;

class B;

class A {
public:
    A() : m_a(5) {};

    ~A() {
        cout << " A is destroyed" << endl;
    }

    void PrintSpB();

    weak_ptr<B> m_sptrB;
    int m_a;
};

class B {
public:
    B() : m_b(10) {};

    ~B() {
        cout << " B is destroyed" << endl;
    }

    weak_ptr<A> m_sptrA;
    int m_b;
};

void A::PrintSpB() {
    if (!m_sptrB.expired()) {
        cout << m_sptrB.lock()->m_b << endl;
    }
}

int main() {
    shared_ptr<B> sptrB(new B);
    shared_ptr<A> sptrA(new A);
    sptrB->m_sptrA = sptrA;
    sptrA->m_sptrB = sptrB;
    sptrA->PrintSpB();
}

unique_ptr

取代原来的auto_ptr

可以工作在数组上

    std::unique_ptr<Stu> ptr(new Stu(20, "qwe"));
    std::unique_ptr<Stu[]> ptr2(new Stu[2]);

提供两个管理资源的方法

  • release(): 只释放拥有关系
  • reset(): 释放拥有关系,销毁资源

参考:

https://stackoverflow.com/questions/2746677/what-happens-when-you-deallocate-a-pointer-twice-or-more-in-c

https://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值