智能指针使用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. 智能指针的核心价值是 "自动释放堆内存",栈内存由系统管理,无需智能指针介入。
相关推荐
Ivanqhz1 分钟前
图着色寄存器分配算法(Graph Coloring)
开发语言·javascript·python·算法·蓝桥杯·rust
Elsa️7463 分钟前
洛谷p5718 复习下快速排序和堆排序
数据结构·算法·排序算法
Frostnova丶6 分钟前
LeetCode 3567.子矩阵的最小绝对差
算法·leetcode·矩阵
夏日听雨眠7 分钟前
文件学习9
数据结构·学习·算法
华农DrLai7 分钟前
什么是自动Prompt优化?为什么需要算法来寻找最佳提示词?
人工智能·算法·llm·nlp·prompt·llama
黎阳之光8 分钟前
十五五智赋新程 黎阳之光以AI硬核技术筑造产业数智底座
大数据·人工智能·算法·安全·数字孪生
2401_8914821710 分钟前
C++中的原型模式
开发语言·c++·算法
皙然10 分钟前
深度解析三色标记算法:JVM 并发 GC 的核心底层逻辑
java·jvm·算法
sali-tec12 分钟前
C# 基于OpenCv的视觉工作流-章40-特征找图
图像处理·人工智能·opencv·算法·计算机视觉
wearegogog12312 分钟前
毫米波MIMO系统仿真中混合预编码的交替最小化算法
算法·预编码算法