debug方式使用stl

  • -D_GLIBCXX_DEBUG

编译时,指定宏 _GLIBCXX_DEBUG 即以 Debug 方式使用 STL 库,效果如下:

#include <string>
#include <stdio.h>
int main(int argc, char* argv[]) {
        std::string str;
        str = "123";
        printf("(%zd)%s\n", str.size(), str.c_str());
        return 0;
}

$ g++ -D_GLIBCXX_DEBUG -std=c++11 -g -o x x.cpp

(gdb) b basic_string.h:207

(gdb) bt
#0  std::string::_Rep::_M_set_length_and_sharable (this=0x604010, __n=3) at /usr/include/c++/4.8.2/bits/basic_string.h:210
#1  0x0000000000401c66 in std::string::_M_mutate (this=0x7fffffffe490, __pos=0, __len1=0, __len2=3) at /usr/include/c++/4.8.2/bits/basic_string.tcc:496
#2  0x0000000000401900 in std::string::_M_replace_safe (this=0x7fffffffe490, __pos1=0, __n1=0, __s=0x401f11 "123", __n2=3) at /usr/include/c++/4.8.2/bits/basic_string.tcc:684
#3  0x00000000004016d7 in std::string::assign (this=0x7fffffffe490, __s=0x401f11 "123", __n=3) at /usr/include/c++/4.8.2/bits/basic_string.tcc:264
#4  0x00000000004015c4 in std::string::assign (this=0x7fffffffe490, __s=0x401f11 "123") at /usr/include/c++/4.8.2/bits/basic_string.h:1131
#5  0x0000000000401449 in std::string::operator= (this=0x7fffffffe490, __s=0x401f11 "123") at /usr/include/c++/4.8.2/bits/basic_string.h:555
#6  0x0000000000401215 in main (argc=1, argv=0x7fffffffe598) at x.cpp:5

(gdb) l
205
206             void
207             _M_set_length_and_sharable(size_type __n)
208             {
209     #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
210               if (__builtin_expect(this != &_S_empty_rep(), false))
211     #endif
212                 {
213                   this->_M_set_sharable();  // One reference.
214                   this->_M_length = __n;
  • stringfwd.h
typedef basic_string<char> string;  

  • basic_string.tcc
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_terminal = _CharT(); // 结尾符号,对于 char 实为 0
  • _Rep
struct _Rep_base
{
    // _M_length:字符串长度
    // 注意:不一定是字节数,
    // 和 _CharT 的类型有关,如果为 char 则为字节数
    size_type _M_length;
    size_type _M_capacity;
    _Atomic_word _M_refcount; // 引用计数
};

struct _Rep: _Rep_base
{
    static const size_type	_S_max_size;
    static const _CharT	_S_terminal;

    void _M_set_sharable()
    {
        this->_M_refcount = 0;
    }
        
    void _M_set_length_and_sharable(size_type __n)
    {
    #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
        if (__builtin_expect(this != &_S_empty_rep(), false))
    #endif
        {
          this->_M_set_sharable();  // One reference. // 置引用计数为 0
          this->_M_length = __n; // 设置长度(不包含任何空结尾符)
          traits_type::assign(this->_M_refdata()[__n], _S_terminal); // 添加空结尾符(null terminated char)
          // grrr. (per 21.3.4)
          // You cannot leave those LWG people alone for a second.
        }
    }

    _CharT* _M_refdata() throw()
    {
        return reinterpret_cast<_CharT*>(this + 1); // 实际指向 _Alloc_hider::_M_p
    }
};
  • _Alloc_hider
struct _Alloc_hider: _Alloc
{
    _CharT* _M_p; // The actual data.
};
  • basic_string.h
template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string
{
    static const size_type npos = static_cast<size_type>(-1);

    mutable _Alloc_hider _M_dataplus;

    // 返回不包含任何空结尾符的字符个数
    // Returns the number of characters in the string, not including any null-termination.
    size_type size() const
    {
        return _M_rep()->_M_length;
    }

    _CharT* _M_data() const
    {
        return  _M_dataplus._M_p;
    }

    _Rep* _M_rep() const
    { 
        return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); // 在 _M_refdata() 中使用时 +1
    }

    basic_string& assign(const _CharT* __s)
    {
        __glibcxx_requires_string(__s);
        return this->assign(__s, traits_type::length(__s));
    }

    template<typename _CharT, typename _Traits, typename _Alloc>
    basic_string<_CharT, _Traits, _Alloc>&
    basic_string<_CharT, _Traits, _Alloc>::assign(const _CharT* __s, size_type __n)
    {
        __glibcxx_requires_string_len(__s, __n);
        _M_check_length(this->size(), __n, "basic_string::assign");
        if (_M_disjunct(__s) || _M_rep()->_M_is_shared())
        {
            return _M_replace_safe(size_type(0), this->size(), __s, __n);
        }
        else
        {
            // Work in-place.
            const size_type __pos = __s - _M_data();
            if (__pos >= __n)
                _M_copy(_M_data(), __s, __n);
            else if (__pos)
                _M_move(_M_data(), __s, __n);
            _M_rep()->_M_set_length_and_sharable(__n);
            return *this;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值