Symbian中窥探C++编程功底

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();是在堆空间里建立一个对象,而堆空间的资源必须由程序员显式的释放掉。

你可能感兴趣的:(编程,C++,c,C#,Symbian)