You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++智能指针实现问题求助:输出结果不符合预期

解决你的C++智能指针输出异常问题

兄弟,你这输出问题一看就是智能指针的内部资源管理彻底乱了——要么是没做引用计数,要么是拷贝/赋值逻辑写错了,导致两个指针抢同一块内存,还出现了野指针(那个4919984就是野指针读出来的垃圾值)。

先给你看修正后的完整代码,保证能输出预期的intOne: 1 intTwo: 10:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <exception>
using namespace std;

template <typename T>
class SmartPointer {
private:
    T* ptr;
    size_t* ref_count; // 用引用计数跟踪资源被多少指针共享

    // 辅助函数:释放当前持有的资源
    void release() {
        if (ref_count) {
            (*ref_count)--;
            // 引用计数归0时才真正释放内存
            if (*ref_count == 0) {
                delete ptr;
                delete ref_count;
            }
        }
        // 重置指针,避免野指针
        ptr = nullptr;
        ref_count = nullptr;
    }

public:
    // 基础构造函数:接收原始指针
    explicit SmartPointer(T* p = nullptr) : ptr(p) {
        if (ptr) {
            ref_count = new size_t(1); // 新资源引用计数初始为1
        } else {
            ref_count = nullptr;
        }
    }

    // 拷贝构造:共享资源,增加引用计数
    SmartPointer(const SmartPointer& other) {
        ptr = other.ptr;
        ref_count = other.ref_count;
        if (ref_count) {
            (*ref_count)++;
        }
    }

    // 赋值运算符:先释放自己的资源,再共享新资源
    SmartPointer& operator=(const SmartPointer& other) {
        if (this != &other) { // 防止自赋值搞崩资源
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            if (ref_count) {
                (*ref_count)++;
            }
        }
        return *this;
    }

    // 移动构造(可选,提升性能,避免不必要的计数操作)
    SmartPointer(SmartPointer&& other) noexcept {
        ptr = other.ptr;
        ref_count = other.ref_count;
        // 把原对象的指针置空,避免它析构时释放资源
        other.ptr = nullptr;
        other.ref_count = nullptr;
    }

    // 移动赋值(可选)
    SmartPointer& operator=(SmartPointer&& other) noexcept {
        if (this != &other) {
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            other.ptr = nullptr;
            other.ref_count = nullptr;
        }
        return *this;
    }

    // 解引用运算符:安全访问对象
    T& operator*() const {
        if (!ptr) {
            throw runtime_error("别解引用空指针啊兄弟!");
        }
        return *ptr;
    }

    // 箭头运算符:访问对象成员
    T* operator->() const {
        if (!ptr) {
            throw runtime_error("空指针不能用->!");
        }
        return ptr;
    }

    // 获取原始指针(谨慎使用,别乱搞)
    T* get() const {
        return ptr;
    }

    // 析构函数:清理资源
    ~SmartPointer() {
        release();
    }
};

int main() {
    SmartPointer<int> intOne(new int(1));
    SmartPointer<int> intTwo(new int(3));
    *intTwo = 10; // 是修改指针指向的对象的值,不是直接给智能指针赋值新指针!

    cout << "intOne: " << *intOne << " intTwo: " << *intTwo << endl;
    return 0;
}

说说你之前代码的核心问题:

  • 没做引用计数:如果你的SmartPointer只是简单持有原始指针,没跟踪共享数量,拷贝/赋值时多个对象会指向同一块内存,修改一个就会影响另一个,析构时还会重复释放内存导致野指针。
  • 赋值逻辑错误:如果你直接给智能指针赋值新原始指针(比如intTwo = new int(10)),但没重载赋值运算符,会导致原内存泄漏,新内存管理混乱。正确做法要么是修改已有对象的值(*intTwo = 10),要么赋值新的智能指针对象(这时候需要重载运算符处理引用计数)。
  • 野指针访问:那个4919984就是因为某个指针指向的内存已被释放,但你还在访问,读出来的垃圾值。

实现智能指针的关键要点:

  • 必须用引用计数跟踪资源共享情况,只有最后一个指针销毁时才释放内存。
  • 必须实现拷贝构造函数和赋值运算符重载,默认浅拷贝会直接复制指针,导致资源管理崩溃。
  • 可选实现移动语义,提升性能,避免不必要的引用计数操作。
  • 解引用和箭头运算符要做空指针检查,避免程序崩溃。

内容的提问来源于stack exchange,提问作者IWantToDie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:08:26