昨天做一個dll,代碼很快寫完了,然而使用得時候總是遇到string內部指針刪除錯誤,郁悶了一天,今天沒去公司,好好研究了一下。
首先看下下面這段代碼,聲明兩個string對象:
std::
string
??s1?
=
?
"
wlwlxj
"
;
std::
string
??s2?
=
?
"
lxjwlwww
"
;
調試狀態下可以看到內部指針:
s1=0x00364ff9
s2=0x00365061
然后執行
s2?
=
?s1;
按下f11,進入xstring源文件:
_Myt
&
?
operator
=
(
const
?_Myt
&
?_X)?????????// 賦值操作符
??
{
return
?(assign(_X));?}?????????????????????// 調用assign函數
繼續進入assign(_X)函數:
_Myt
&
?assign(
const
?_Myt
&
?_X)
????????
{
return
?(assign(_X,?
0
,?npos));?}???// 調用assign函數
_Myt&?assign(const?_Myt&?_X,?size_type?_P,?size_type?_M)
????????
{if?(_X.size()?<?_P)
????????????_Xran();
????????size_type?_N?=?_X.size()?-?_P;
????????if?(_M?<?_N)
????????????_N?=?_M;
????????if?(this?==?&_X)
????????????erase((size_type)(_P?+?_N)),?erase(0,?_P);
????????else?if?(0?<?_N?&&?_N?==?_X.size()????????????????????????// 這個分支意思就是如果拷貝源有內容且就是就是源本身,并且
????????????&&?_Refcnt(_X.c_str())?<?_FROZEN?-?1??????????// 源字符串引用次數少于255-1次(可見引用次數最多255次),
????????????&&?allocator?==?_X.allocator)???????????????????????????//且源字符和目的字符分配器一致
????????????
{_Tidy(true);?????????????????????????????????????????????// 刪除本身
????????????_Ptr?=?(_E?*)_X.c_str();????????????????????????????????????// 復制內容到目的串
????????????_Len?=?_X.size();
????????????_Res?=?_X.capacity();
????????????++_Refcnt(_Ptr);?}?????????????????????????????????????????????// 增加一次引用
????????else?if?(_Grow(_N,?true))
????????????
{_Tr::copy(_Ptr,?&_X.c_str()[_P],?_N);
????????????_Eos(_N);?}
????????return?(*this);?}這樣結果就是調用=號以后,s2地址和s1地址一樣,都是0x00364ff9。
假如我們動態庫有這樣一個類class DLL接口:
SetString(std::string?str)

{
m_str?=?str;
}
在客戶調用時候:
std::string?str?=?"wlwlxj";
DLL?d;
d.SetString(str);?//?此時沒有深拷貝,而是引用了str內部指針地址解決方法就是避免std::string引用計數,接口處修改為SetString(const char*),這樣在dll內部分配內存,內部釋放,就不會有問題。


