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

自定义MyException类为何在Linux下产生乱码信息?

问题分析:自定义异常类在Linux下输出乱码的原因

先看你的异常类实现代码:

class MyException: public std::exception
{
  private:
   std::string m_message;
   bool m_internalError;
  
  public:
   MyException(bool internal_err, std::string msg)
   : m_message(std::move(msg)), 
     m_internalError(internal_err)
   {
   }

   const char* what() const noexcept override
   {
      std::ostringstream msg;
      msg << m_internalError << ": " << m_message;
      std::string full_msg = msg.str();
      return full_msg.c_str();
   }
};

问题描述

上述自定义异常类在Windows系统中运行正常,但在Linux系统下会输出乱码信息。若从ostringstream中移除m_message则恢复正常,请问该问题的原因是什么?

核心原因

问题本质是悬空指针引发的未定义行为,差异源于不同系统的内存管理策略:

  • what()函数里的full_msg是局部字符串对象,函数执行完毕后,该对象会被销毁,其内部的字符数组也会被回收。而你返回的full_msg.c_str()指向的就是这块即将被释放的内存,属于悬空指针。
  • Windows和Linux的栈内存处理逻辑不同:Windows下函数返回后,栈上的内存可能暂时不会被覆盖,所以悬空指针还能侥幸读到原有内容;但Linux下栈内存会被快速复用或清理,此时访问悬空指针就会得到乱码或无意义的数据。
  • 移除m_message后看似正常只是巧合:即便去掉m_message,悬空指针的问题依然存在,只是生成的字符串更短,内存覆盖的概率更低,但这依然是未定义行为,随时可能出问题。

正确解决方式

应该把拼接好的完整消息存储为异常类的成员变量,确保返回的指针指向的内存不会随函数结束而销毁。比如在构造函数中完成消息拼接:

class MyException: public std::exception
{
  private:
   std::string m_fullMessage;
  
  public:
   MyException(bool internal_err, std::string msg)
   {
      std::ostringstream oss;
      oss << internal_err << ": " << msg;
      m_fullMessage = oss.str();
   }

   const char* what() const noexcept override
   {
      return m_fullMessage.c_str();
   }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:35:00