智能指针使用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. 智能指针的核心价值是 "自动释放堆内存",栈内存由系统管理,无需智能指针介入。
相关推荐
Dlrb121114 小时前
C语言-指针三
c语言·算法·指针·const·命令行参数
Tisfy14 小时前
LeetCode 2540.最小公共值:双指针(O(m+n))
算法·leetcode·题解·双指针
IronMurphy14 小时前
【算法四十七】152. 乘积最大子数组
算法
REDcker14 小时前
有限状态机与状态模式详解 FSM建模Java状态模式与C++表驱动模板实践
java·c++·状态模式
basketball61615 小时前
C++ 构造函数完全指南:从入门到进阶
java·开发语言·c++
淘矿人16 小时前
Claude辅助DevOps实践
java·大数据·运维·人工智能·算法·bug·devops
Cosolar16 小时前
万字详解:RAG 向量索引算法与向量数据库架构及实战
数据库·人工智能·算法·数据库架构·milvus
想唱rap16 小时前
IO多路转接之poll
服务器·开发语言·数据库·c++
落羽的落羽17 小时前
【算法札记】练习 | Week4
linux·服务器·数据结构·c++·人工智能·算法·动态规划