指针

前提: 内存天然有编号 → 编号叫地址。每个地址对应一个 字节(1B)。 内存的基本操作单元就是字节,如果想要操作比特呢? 需要运用_位运算_ 内存的开辟->堆区 由程序员手动管理! 开辟内存的本质 是操作系统分配空闲物理页映射到对应的虚拟内存页供开发者使用 涉及到内核态的系统调用!

涉及到内存管理:

unique_ptr → 节点独占所有权,修改时直接转移所有权或复制(唯一所有权,同一时间只有一个 unique_ptr 拥有对象。)

std::unique_ptr<Node> p1(new Node());
auto p2 = std::move(p1); // p1 不再拥有,p2 拥有

shared_ptr → 多个版本共享节点(只读时共享)

std::shared_ptr<Node> p1 = std::make_shared<Node>();
std::shared_ptr<Node> p2 = p1; // 引用计数+1
// 当最后一个持有者销毁时,自动释放

weak_ptr → 避免循环引用(例如缓存、索引指向父子关系时)(解决shared_ptr的循环引用问题)

问题:

struct Node {
    std::shared_ptr<Node> next;
};

auto n1 = std::make_shared<Node>();
auto n2 = std::make_shared<Node>();
n1->next = n2;
n2->next = n1;  // 互相持有shared_ptr,引用计数永远不为0,内存泄漏

std::weak_ptr<Node> wp = p1;  // 不影响引用计数
if (auto sp = wp.lock()) {    // 转换为 shared_ptr
    // 安全访问对象
}

三个智能指针 为 解决因传统的 指针开辟空间空 程序员 忘记 释放所导致的_内存泄露_问题!