智能指针使用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. 智能指针的核心价值是 "自动释放堆内存",栈内存由系统管理,无需智能指针介入。
相关推荐
ʚB҉L҉A҉C҉K҉.҉基҉德҉^҉大4 分钟前
C++中的策略模式进阶
开发语言·c++·算法
Zach_yuan16 分钟前
C++ Lambda 表达式从入门到进阶
开发语言·c++
郝学胜-神的一滴18 分钟前
Linux网络编程之Socket函数:构建通信的桥梁
linux·服务器·网络·c++·程序人生
weixin_4454023020 分钟前
模板元编程应用场景
开发语言·c++·算法
啊阿狸不会拉杆20 分钟前
《机器学习导论》第 1 章 - 引言
人工智能·python·算法·机器学习·ai·numpy·matplotlib
轻轻唱23 分钟前
2026专业PPT设计服务商推荐:TOP10深度评测与选择指南
大数据·人工智能·算法
s1hiyu24 分钟前
嵌入式C++低功耗设计
开发语言·c++·算法
fanstuck28 分钟前
从 0 到 1 构建企业智能体平台:openJiuwen 架构解析与智能客服工作流实战
大数据·人工智能·算法·架构·aigc
青桔柠薯片29 分钟前
数据结构:单向链表和双向链表
数据结构·算法·链表
2401_8414956431 分钟前
【LeetCode刷题】对称二叉树
数据结构·python·算法·leetcode·二叉树··递归