C++ - 继承ostream在Android上崩溃但不在Windows上崩溃

Kai*_*aan 2 c++ windows io android iostream

我已经实现了一个简单的ostream和streambuf类.出于某种原因,当我尝试实例化我的AndroidLogOStream对象时它会崩溃.

注意:我的Application.mk中有stlport_static

class AndroidLogStreamBuf : public std::streambuf
    {
    public:
        inline AndroidLogStreamBuf() : std::streambuf()
        {
            //std::cout << "asdfg";

        }

        inline ~AndroidLogStreamBuf()
        {

        }



    };

    class AndroidLogOStream : public std::ostream
    {
    public:
        inline AndroidLogOStream() : std::ostream(&mBuf)
        {

        }

        inline ~AndroidLogOStream()
        {

        }

    private:
        AndroidLogStreamBuf mBuf;
    };
Run Code Online (Sandbox Code Playgroud)

它是准系统,它在窗户上运行良好.它在android上编译很好,但由于某种原因它崩溃了.它试图执行的最后一行是_streambuf.c:46:

template <class _CharT, class _Traits>
locale
basic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc) {
  this->imbue(__loc);          <---- crash
  locale __tmp = _M_locale;
  _M_locale = __loc;
  return __tmp;
}
Run Code Online (Sandbox Code Playgroud)

当然,我对iostreams仍感到困惑,但构造函数一定有问题,我想它无效?

Dan*_*lme 5

在构造函数中,首先初始化基类,然后是所有成员.当你调用基类构造函数时std::ostream,你传递的是mBuf尚未构造的地址.访问尚未构造的对象具有未定义的行为.

要解决这个问题,您可以按如下方式重新设计类:

class AndroidLogStreamBuf : public std::streambuf
{
public:
    AndroidLogStreamBuf() : std::streambuf()
    { }

    ~AndroidLogStreamBuf()
    { }
};

class AndroidLogOStream : public std::ostream
{
public:
    AndroidLogOStream(AndroidLogStreamBuf *buf) :
        std::ostream(buf),
        mBuf(buf)
    { }

    ~AndroidLogOStream()
    { }

private:
    AndroidLogStreamBuf *mBuf;
};

class AndroidLogOStreamWithBuf
{
private:
    AndroidLogStreamBuf mBuf;
    AndroidLogOStream mStream;

public:
    AndroidLogOStreamWithBuf() :
        mBuf(&mStream),
        mStream()
    { }

    virtual ~AndroidLogOStreamWithBuf()
    { }

    AndroidLogOStream& getOStream()
    {
        return mStream;
    }
};
Run Code Online (Sandbox Code Playgroud)

注意我声明的顺序mBufmStream输入AndroidLogOStreamWithBuf:两个字段将按顺序初始化,无论它们出现在构造函数初始化列表中的顺序如何.另外,inline在原始代码中标记成员函数是多余的:当您在类定义中定义成员函数时,它会自动标记为inlinable.

这对你的系统来说是否是一个合理的设计取决于你打算如何使用这些类,但答案可能是"不".