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

C++模板类Address无法正确返回指向数据的问题求助

问题:unique_ptr实例化模板类后无法正确获取指针指向的数据

我定义了如下C++模板类Address,通过std::unique_ptr实例化后,输出结果中Item字段为空,使用char或int类型均存在该问题,请问如何正确获取指针指向的数据?

原代码

#include <iostream>
#include <memory>

template <typename T> class Address
{
    private:
        T* ptr;
        size_t size;
    public:
        Address(T item) : ptr(&item), size(sizeof(item)) {}
        T getItem() const 
        {
            return *ptr;
        }
        long getAddress() const
        {
            return (long int ) ptr;
        }
        long getSize() const
        {
            return size;
        }        
};

template <typename T> 
std::ostream& operator<<(std::ostream& out, const Address<T> item)
{
    out << "\nItem: " << item.getItem() << "\n";
    out << "Address : " << item.getAddress() << "\n";
    out << "Size : " << item.getSize() << "\n";
    return out;
}

int main()
{
    std::unique_ptr<Address<char>> ptr_addressObj(new Address('P'));
    std::cout<< *ptr_addressObj << "\n";
}

运行结果

Item: 
Address : 140720983114340
Size : 1

问题根源

构造函数Address(T item)中的参数item是临时拷贝变量,构造函数执行完毕后该临时变量会被销毁,此时类成员ptr指向的是一块已释放的内存,后续访问*ptr属于未定义行为,所以输出的Item为空或乱值——这和是否使用unique_ptr无关,本质是悬空指针问题。

修复方案

方案一:类自行管理内存(适合必须用指针的场景)

修改构造函数为成员指针分配独立内存并拷贝值,同时添加析构函数释放内存,避免内存泄漏:

template <typename T> class Address
{
    private:
        T* ptr;
        size_t size;
    public:
        // 用const引用接收参数,减少不必要拷贝
        Address(const T& item) : ptr(new T(item)), size(sizeof(T)) {}
        
        // 析构函数释放内存
        ~Address() { delete ptr; }
        
        // 禁用拷贝构造和赋值,避免double free问题
        Address(const Address&) = delete;
        Address& operator=(const Address&) = delete;
        
        T getItem() const 
        {
            return *ptr;
        }
        long getAddress() const
        {
            return (long int ) ptr;
        }
        long getSize() const
        {
            return size;
        }        
};

方案二:直接存储值(更简单,无指针风险)

既然类仅需保存单个元素,没必要使用指针,直接存储值即可:

#include <iostream>
#include <memory>

template <typename T> class Address
{
    private:
        T item;
        size_t size;
    public:
        Address(T item) : item(item), size(sizeof(item)) {}
        T getItem() const 
        {
            return item;
        }
        // 获取存储值的内存地址
        long getAddress() const
        {
            return (long int ) &item;
        }
        long getSize() const
        {
            return size;
        }        
};

// 用const引用接收参数,避免不必要拷贝
template <typename T> 
std::ostream& operator<<(std::ostream& out, const Address<T>& item)
{
    out << "\nItem: " << item.getItem() << "\n";
    out << "Address : " << item.getAddress() << "\n";
    out << "Size : " << item.getSize() << "\n";
    return out;
}

int main()
{
    std::unique_ptr<Address<char>> ptr_addressObj(new Address('P'));
    std::cout << *ptr_addressObj << "\n";
}

修复后运行结果

Item: P
Address : 140720983114340
Size : 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:15:05