智能指针使用bug

bug源码:

复制代码
#include<myhead.h>
int main(int argc, const char *argv[]){
 
    //智能指针demo
    int num=666;

    // int* p1=&num;

    shared_ptr<int> sp1=&num;

    cout<<*sp1<<endl;


    return 0;
}

一、Bug 核心原因分析

这段代码的致命错误 是:用栈内存的地址直接初始化 shared_ptr ,违背了 shared_ptr 的设计初衷,会触发未定义行为(程序崩溃 / 段错误)。

详细拆解:
  1. shared_ptr 的核心职责shared_ptr 是 C++ 智能指针,专门用于管理动态分配的堆内存 (通过 new/malloc 分配),其析构函数会自动调用 delete 释放所管理的指针指向的内存,避免内存泄漏。

  2. 代码中的内存类型问题int num = 666; 中,num栈上的局部变量 (栈内存由操作系统自动管理,生命周期随作用域结束而销毁,不允许手动调用 delete)。而 shared_ptr<int> sp1 = &num; 直接将栈内存地址交给 shared_ptr 管理,当 sp1 生命周期结束(比如函数执行完毕)时,sp1 的析构函数会执行 delete &num; ------ 栈内存不允许被 delete 释放,这会触发未定义行为 (通常表现为程序崩溃、段错误 Segmentation fault)。

  3. 补充:表面 "正常" 的假象代码中 cout << *sp1 << endl; 可能暂时打印出 666,但这只是巧合(此时 sp1 还未析构,栈内存仍有效),本质是严重的内存管理错误,程序运行到 sp1 析构时必然出错。

二、Bug 解决方案(分场景给出最优写法)

场景 1:管理 "动态分配的堆内存"(推荐,符合 shared_ptr 设计初衷)

shared_ptr 应管理堆内存,需通过 new 分配内存后初始化,或用更安全的 make_shared(C++11 及以上)。

方案 1:用 new 初始化 shared_ptr

cpp

运行

复制代码
#include <iostream>
#include <memory> // 必须包含智能指针头文件
using namespace std;

int main() {
    // 1. 动态分配堆内存(int值为666)
    int* p_num = new int(666);
    // 2. 用堆内存地址初始化shared_ptr(正确)
    shared_ptr<int> sp1(p_num);
    
    cout << *sp1 << endl; // 输出:666
    
    // 无需手动delete,sp1析构时会自动delete p_num
    return 0;
}
方案 2:用 make_shared 初始化(更优,避免裸指针)

make_shared 是 C++11 引入的推荐写法,直接分配堆内存并构造 shared_ptr,避免裸指针暴露,降低内存泄漏风险:

cpp

运行

复制代码
#include <iostream>
#include <memory>
using namespace std;

int main() {
    // 直接创建管理堆内存的shared_ptr(推荐)
    shared_ptr<int> sp1 = make_shared<int>(666);
    
    cout << *sp1 << endl; // 输出:666
    
    return 0;
}
场景 2:非要管理栈变量(不推荐,仅作知识补充)

如果确实需要让 shared_ptr 指向栈变量(无实际业务意义,违背设计初衷),需自定义空删除器 (告诉 shared_ptr 析构时不执行 delete):

cpp

运行

复制代码
#include <iostream>
#include <memory>
using namespace std;

int main() {
    int num = 666;
    // 自定义删除器:空函数(不做任何操作)
    auto no_op_delete = [](int*) {};
    // 用空删除器初始化shared_ptr,避免析构时delete栈内存
    shared_ptr<int> sp1(&num, no_op_delete);
    
    cout << *sp1 << endl; // 输出:666
    
    // sp1析构时调用no_op_delete,不会执行delete,避免崩溃
    return 0;
}

⚠️ 注意:此方案仅为 "规避崩溃",但失去了 shared_ptr 自动管理内存的意义,实际开发中严禁这样用

三、关键注意事项(新手必记)

  1. shared_ptr/unique_ptr 等智能指针,仅用于管理堆内存,绝对不能绑定栈内存地址;
  2. 包含智能指针必须加头文件 <memory>,否则会编译报错;
  3. 优先使用 make_shared 创建 shared_ptr,而非直接用 new(减少内存泄漏风险,提升性能);
  4. 智能指针的核心价值是 "自动释放堆内存",栈内存由系统管理,无需智能指针介入。
相关推荐
NAGNIP2 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
端平入洛9 小时前
delete又未完全delete
c++
颜酱11 小时前
单调栈:从模板到实战
javascript·后端·算法
CoovallyAIHub14 小时前
仿生学突破:SILD模型如何让无人机在电力线迷宫中发现“隐形威胁”
深度学习·算法·计算机视觉
CoovallyAIHub14 小时前
从春晚机器人到零样本革命:YOLO26-Pose姿态估计实战指南
深度学习·算法·计算机视觉
CoovallyAIHub14 小时前
Le-DETR:省80%预训练数据,这个实时检测Transformer刷新SOTA|Georgia Tech & 北交大
深度学习·算法·计算机视觉
CoovallyAIHub14 小时前
强化学习凭什么比监督学习更聪明?RL的“聪明”并非来自算法,而是因为它学会了“挑食”
深度学习·算法·计算机视觉
CoovallyAIHub15 小时前
YOLO-IOD深度解析:打破实时增量目标检测的三重知识冲突
深度学习·算法·计算机视觉
NAGNIP1 天前
轻松搞懂全连接神经网络结构!
人工智能·算法·面试
NAGNIP1 天前
一文搞懂激活函数!
算法·面试