I have implemented a simple ostream and streambuf class. For some reason, it crashes when I try to instantiate my AndroidLogOStream object.
Note: I have stlport_static in my Application.mk
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;
};
It’s barebones, and it runs fine on windows. It compiles fine on android, but it crashes for some reason. The last line it tries to execute is in _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;
}
Granted I am still quite confused on iostreams, but it must be something wrong with the constructor, I suppose it is not valid?
In a constructor, the base class is initialized first, followed by all of the members. When you call the base class constructor
std::ostream, you’re passing it the address ofmBuf, which has not yet been constructed. Accessing an object that hasn’t yet been constructed has undefined behaviour.To get around this, you could redesign your classes as follows:
Notice the order I’ve declared
mBufandmStreaminAndroidLogOStreamWithBuf: the two fields will be initialized in that order, regardless of the order they appear in the constructor initializer list. As an aside, marking the member functions asinlinein your original code was superfluous: when you define a member function within the class definition, it’s automatically marked as inlinable.Whether this is a sensible design for your system depends on how you’re intending to use these classes, but the answer is probably “no”.