1. 程式人生 > >C++踩坑記錄(一)std:;string的析構

C++踩坑記錄(一)std:;string的析構

開發十年,就只剩下這套架構體系了! >>>   

越學C++越覺得自己菜了
之前寫服務端程式有一個往訊息佇列裡面推json的過程,然後發現推進去C#端取到的無論如何都是個空指標
簡單復現一下現場

string str1 = string("hello1");
string str2 = string("hello2");
const char* ptr1 = str1.substr(1).data();    // 取字串從下標1到結尾的部分
const char* ptr2 = str2.substr(1).data();
cout << ptr1 << ptr2 << endl;

這樣看起來輸出是ello1ello2的輸出,在我筆記本上面挺正常的,實際上我整合到伺服器上面的時侯炸了,一直取到一組奇怪的字串
跟蹤除錯了一早上(雖然寫了3年C++工程,但是還是菜吧,折騰了好久)。
原來在str1.substr(1)建立了一個臨時物件儲存str1的子串。data()函式獲取了這個子串的記憶體指標。

執行到到了下一行的時候,儲存str1子串的字串物件被析構,msvc發現這是個臨時物件,程式碼塊還沒結束的十好幾就把記憶體析構掉,臨時物件的記憶體被釋放,同時str2.substr(1),這個時候新的臨時變數被註冊到剛才str1.substr(1)被析構掉的記憶體地址上面,此時再去呼叫data(),拿到了ptr1同一個地址的指標,此時記憶體的資料變更為s2的子串,然後壓到訊息隊裡面的資料穿就亂了,當我把程式增加一個臨時string去接收上面產生的子串的時候,問題就會解決了

string str1 = string("string1");
string str2 = string("string2");
string t_str1 = str1.substr(1);
string t_str2 = str2.substr(1);
const char* ptr1 = t_str1.data();
const char* ptr2 = t_str2.data();
cout << ptr1 << ptr2 << endl;

此時輸出正常
踩坑日常