MyString& StrUtil::newMyStringfromTDesC16(TDesC16& aDesC16) { HBufC8* hBuf8 = HBufC8::New(aDesC16.Length() * 3); MyString ret; if (hBuf8) { TPtr8 aPtr8(hBuf8->Des()); TInt cvtResult = CnvUtfConverter::ConvertFromUnicodeToUtf8(aPtr8, aDesC16); ret.assign((const char *)(hBuf8->Ptr()), hBuf8->Size()); if (cvtResult != 0) { } delete hBuf8; hBuf8 = NULL; } return ret; } |
我們知道,C++中的記憶體分為堆和棧(忽略全域變數區ect),棧是存放臨時變數的,棧內的資源在生命週期結束後會被釋放掉。之所以這樣做,是因為棧的資源一般來說是非常有限的。
那麼上面那段程式中MyString ret;這句是在棧上建立一個臨時對象
然後return ret;這句返回這個臨時對象
但是不幸的是,ret遇到下面的}時生命週期結束,於是被釋放掉!所以這段程式的傳回值指向了一段已經被釋放了的記憶體地區,於是出現不可知的bug。
改成下面即可:
MyString& StrUtil::newMyStringfromTDesC16(TDesC16& aDesC16) { HBufC8* hBuf8 = HBufC8::New(aDesC16.Length() * 3); MyString *ret = new MyString(); if (hBuf8) { TPtr8 aPtr8(hBuf8->Des()); TInt cvtResult = CnvUtfConverter::ConvertFromUnicodeToUtf8(aPtr8, aDesC16); ret->assign((const char *)(hBuf8->Ptr()), hBuf8->Size()); if (cvtResult != 0) { } delete hBuf8; hBuf8 = NULL; } return *ret; } |
MyString *ret = new MyString();是在堆空間裡建立一個對象,而堆空間的資源必須由程式員顯式的釋放掉。