std::basic_string
构造函数
basic_string
有个16字节栈区空间,假如写入的字节数不超过15,是存放在栈上的,不会malloc内存。
enum { _S_local_capacity = 15 / sizeof(_CharT) };
union
{
_CharT _M_local_buf[_S_local_capacity + 1];
size_type _M_allocated_capacity;
};
拷贝构造
basic_string(const basic_string& __str)
未采用读时共享写时复制的思想。即会对原来的内存拷贝一份。
以下代码在debug下跑可正常运行
std::string str1 = "Hello World Hello World";
std::string str2 = str1;
assert(str1.c_str() != str2.c_str();
resize误区
resize
作用是修改当前字符串长度,会扩容但不会缩小空间,想要缩小空间可在resize后调用shrink_to_fit
template <typename _CharT, typename _Traits, typename _Alloc>
void basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)
{
const size_type __size = this->size();
if (__size < __n)
this->append(__n - __size, __c);
else if (__n < __size)
this->_M_set_length(__n);
}
reserve误区
reserve
实际上不会减少空间,比如本来capacity() == 128
,reserve(64)
是不会做任何操作的
有个无参数版本的reserve()
,实际作用就是将容量缩减到合适大小
shrink_to_fit()
就是直接调用的reserve()
template <typename _CharT, typename _Traits, typename _Alloc>
void basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res)
{
const size_type __capacity = capacity();
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2968. Inconsistencies between basic_string reserve and
// vector/unordered_map/unordered_set reserve functions
// P0966 reserve should not shrink
if (__res <= __capacity)
return;
pointer __tmp = _M_create(__res, __capacity);
this->_S_copy(__tmp, _M_data(), length() + 1);
_M_dispose();
_M_data(__tmp);
_M_capacity(__res);
}
clear误区
clear()
函数会修改长度变量还会将首个字符初始化。初始化成某个值要看编译器的行为。
void clear() noexcept
{
_M_set_length(0);
}
void _M_set_length(size_type __n)
{
_M_string_length = __length;
traits_type::assign(_M_data()[__n], _CharT()); // _CharT()对于字符串类型来说就是char()
}
size和length误区
一般思维认为size()
表示字符串所占字节数,length()
表示字符串中字符个数,但实际size()
和length()
都表示字符串的字符个数。
即在utf16/utf32/GBK
等编码方式下,字符串的实际字节数不等于size()
,比如utf16
编码字符串,需要将length()
乘以2得到总字节数。
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_string_length; }
size_type
length() const _GLIBCXX_NOEXCEPT
{ return _M_string_length; }
std::thread
用的posix线程库接口,pthread
在头文件std_thread.h定义
线程入口函数execute_native_thread_routine
在这个函数执行_State::_M_run
方法做到可接受任意参数和返回值的函数
需要注意的是join和detach都会抛出异常,并且都是线程不安全的,会对_M_id
成员变量未加锁访问。
通过pthread_detach
和pthread_join
返回错误,然后抛出异常