这种使用std::string的方式安全吗?

Is this way of using std::string safe?

本文关键字:方式 安全 string std      更新时间:2023-10-16

我正在写一个字符串类(Utf8String),它包装(有)一个std::string(因为它很方便)。

由于某种原因,我必须访问包装后的std::string的内部缓冲区,以便直接写入它。我知道这是肮脏的,违反了封装原则,但我必须这样做。

让以下Utf8String类成员:

std::basic_string< char > m_sBuf;
inline char * Reserve( uint32_t nNewByteCap )
{
   m_sBuf.reserve( nNewByteCap );
   return const_cast< char * >( m_sBuf.c_str() );
}
inline void Resize( uint32_t nNewByteCount )
{
   // Some stuff ...
   m_sBuf.resize( nNewByteCount, ' ' );
}

为了做这样的事情:

Utf8String sMessage;
char * sBuffer = sMessage.Reserve( 1024 );
uint32_t nRealLen = some_c_function_write_to_buffer( sBuffer, sMessage.Capacity() );
sMessage.Resize( nRealLen );

我不确定STL内部是如何工作的。据我所知,它接受在std::字符串中间丢失空字符,因此在字符串实际结束之前放置空字符应该不是问题。

由于STL的实现在不同的平台上可能是不同的,所以在我的平台上测试并不意味着它也可以在其他平台上工作。

你在这段代码中看到可以破坏std::string对象的东西了吗?谢谢你的帮助。

PS:我不能使用c++ 11.

From http://en.cppreference.com/w/cpp/string/basic_string/c_str:

写入通过c_str()访问的字符数组是未定义的行为。你不应该那样做。

安全代码:

Utf8String sMessage;
std::array<char, 1024> buffer;
uint32_t nRealLen = some_c_function_write_to_buffer( buffer.data(), buffer.size() );
sMessage.Assign(sBuffer.begin(), sBuffer.end());

最后一行假设您的字符串类中有:

template<typename InIt>
void Assign(InIt begin, InIt end) {
    m_sBuf.assign(begin, end);
}

(或同等)。

这是更好的,因为它不使用访问c_str返回的数据,也不试图手动管理std::string中的内存