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

从shared_ptr<std::string>返回const char*后无法在std::cout中显示字符

代码问题排查及修复

问题代码

#include <iostream>
#include <string>

const char* read_from_stdin(void) {
    std::shared_ptr<std::string> m_buffer(new std::string);
    std::getline(std::cin, *m_buffer);
    if (!std::cin.good())
        return nullptr;

    while (!m_buffer->empty() && (m_buffer->back() == '\r') || (m_buffer->back() == '\n')) {
        m_buffer->pop_back();
    }

    return reinterpret_cast<const char*>(m_buffer->c_str());
}

int main()
{
   std::cout << "You entered: " << read_from_stdin() << "\n";
}

运行环境

Windows 11系统,使用Microsoft Visual Studio调试模式运行,暂未检查UTF-8编码问题。

运行现象

程序输出乱码内容,而非输入的正常文本。调试时可观察到shared_ptr<T>对象内部[ptr]指向的字符为正常输入的英文。

问题根源

这段代码存在悬空指针问题:
read_from_stdin函数中的m_buffer是局部shared_ptr,函数执行完毕返回时,该智能指针会被销毁,其管理的std::string对象也会随之释放。但函数返回的c_str()是指向该string内部缓冲区的指针,此时缓冲区已被释放,后续在main中访问该指针属于未定义行为,表现为输出乱码。另外原代码的逻辑运算符优先级存在错误,&&优先级高于||,导致循环条件不符合预期。

修复方案

方案一:返回std::string对象(推荐)

直接返回字符串对象,利用C++返回值优化避免额外拷贝,同时保证对象生命周期正常,还修正了逻辑运算符优先级问题:

#include <iostream>
#include <string>

std::string read_from_stdin(void) {
    std::string m_buffer;
    std::getline(std::cin, m_buffer);
    if (!std::cin.good())
        return {};

    while (!m_buffer.empty() && (m_buffer.back() == '\r' || m_buffer.back() == '\n')) {
        m_buffer.pop_back();
    }

    return m_buffer;
}

int main()
{
   std::cout << "You entered: " << read_from_stdin() << "\n";
}

方案二:延长字符串生命周期(不推荐)

若必须返回const char*,需确保string对象生命周期覆盖指针使用周期,比如将shared_ptr改为全局变量:

#include <iostream>
#include <string>
#include <memory>

std::shared_ptr<std::string> global_buffer;

const char* read_from_stdin(void) {
    global_buffer.reset(new std::string);
    std::getline(std::cin, *global_buffer);
    if (!std::cin.good())
        return nullptr;

    while (!global_buffer->empty() && (global_buffer->back() == '\r' || global_buffer->back() == '\n')) {
        global_buffer->pop_back();
    }

    return global_buffer->c_str();
}

int main()
{
   std::cout << "You entered: " << read_from_stdin() << "\n";
}

注:全局变量会带来额外的维护问题,非必要不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:58:10