日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

释放参数BSTR使用误区以及隐藏的内存破坏和内存泄漏

發布時間:2024/1/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 释放参数BSTR使用误区以及隐藏的内存破坏和内存泄漏 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PS:明天上午,非常郁悶,有很多簡單基礎的問題搞得我有些迷茫,哎,代碼幾天不寫就忘。目前又不當COO,還是得用心記代碼哦!

????BSTR應用誤區以及隱藏的內存損壞和內存泄漏

????

????作者:magictong

????

????簡介

????BSTR的數據結構是什么模樣并非本文討論的問題,但是卻是本文的基礎。在處理COM的跨平臺編程的問題時,需要定義一種通用的字符串類型,它就這樣被發明白,而且它的結構很輕易匹配到不同的編程環境中,對于C++程序員來講,要記著的最基本的一點就是分配BSTR結構時,并非簡單的調用newmalloc就能夠實現的,而且大部分的字符串相關的APIC庫函數也是不能用于處理BSTR的,其實這也是應用BSTR的誤區之一,在C++里面,BSTR被簡單的definewchar_t*,這也是輕易引發誤解的原因之一。

????明天注意討論一下BSTR作為函數的參數、返回值時,調用者和被調用者操作BSTR時扮演的不同角色問題。首先需要注意的時,在必須應用BSTR時盡量應用BSTR的包裝類CComBSTR,它會給你額定實現一些資源的管理工作,令你省力不少,犯錯的可能性也就大大降低了。

????像一個很簡單自然的用法:BSTR?bstrInfo?=?L””,實際上是錯誤的(當然如果你說我當前就把bstrInfo完全當成wchar_t*來應用,那我無話可說)。對于一個BSTR變量來講,它只多是NULL或者正確分配的BSTR指針。

????

????BSTR當成參數和返回應用的基本約定

????1、[in\out]參數

????譬如函數:void?GetChangBSTR(BSTR*?pbstrTitle),在GetChangBSTR函數外部需要先讀取pbstrTitle的值應用,然后改變pbstrTitle的值。

????這類情況下被調用者(也就是GetChangBSTR)在給pbstrTitle賦新值前,需要先釋放pbstrTitle里面本來的值,然后再給pbstrTitle分配上新的值。

????而調用者(也就是調用GetChangBSTR的函數),在傳參之前需要先給pbstrTitle賦值上正確的值,調用結束之后還需要再釋放pbstrTitle的值。

????

????2、[in]參數

????譬如函數:void?PutText(BSTR?bstrText),在PutText外部僅需讀取bstrText的值。

????這類情況下被調用者可以隨意讀取bstrText的值,不需要做其它操作。

????而調用者,在傳參之前需要先給bstrText賦上正確的值,調用結束后需要釋放bstrText的值。

????

????3、[out]參數

????譬如函數:void?GetText(BSTR*?pbstrText),在GetText外部直接給pbstrText賦值。

????這類情況下被調用者直接給pbstrText賦值便可,不需要做其它操作。

????而調用者,在傳參之前不能給pbstrText賦值,調用結束后需要釋放pbstrText的值。

????

????4、返回參數

????譬如函數:BSTR?GetText(),在GetText外部會返回一個BSTR出來。調用者直接返回一個有效的BSTR便可,而調用者需要釋放這個返回的BSTR

????

????BSTR當成參數和返回應用的誤區

????1、[in\out]參數

????這類情況下,被調用者如果沒有給參數賦值,不要釋放原始值,因為根據約定調用者還會釋放一次,這樣會造成多次釋放,可能致使內存損壞。

????void?GetChangBSTR(/*[in\out]?*/BSTR*?pbstrTitle)

????{

????//?using?the?bs?here

????DoSomething(*pbstrTitle);

?????

????if?(...)

????{

????::SysReAllocString(*pbstrTitle,?_T("Tecnet"));

????}

????else

????{

????::SysFreeString(*pbstrTitle);?//?這里的做法是錯誤的。

????}

????return;

????}

????

????2、[in]參數

????被調用者不要對參數停止釋放操作,原因和上面相同,調用者還會重復釋放一次,可能致使內存損壞。

????void?PutText(/*[in]?*/BSTR?bstrText)

????{

????//?using?the?bs?here

????DoSomething(bstrText);

????::SysFreeString(bstrText);?//?這里的做法是錯誤的。

????

????return;

????}

????

????3、[out]參數

????如果調用者在傳參之前給參數賦值,參數傳遞給被調用者之后,在改變值之前是沒有釋放操作的,也就是說會有內存泄漏。

????void?GetText(/*[out]?*/BSTR*?pbstrText)

????{

????::SysAllocString(*pbstrText,?_T("Tecnet"));

????return;

????}

????//?use?GetText

????BSTR?bstrText;

????::SysAllocString(bstrText,?_T("qq"));

????GetText(&bstrText);

????::SysFreeString(bstrText);?//?很可憐,這里實際上只釋放了一次

????

????4、返回參數

????被調用者不要釋放(不管是直接還是直接致使的)返回給調用者的BSTR,因為調用者會釋放。

????BSTR?GetText()

????{

????BSTR?bstrText?=?::SysAllocString(bstrText,?_T("Tecnet"));

????::SysFreeString(bstrText);?//?這里釋放就喜劇了

????return?bstrText;

????}

????//?use?GetText

????BSTR?bstrText?=?GetText(&bstrText);

????//?use?bstrText

????DoSome(bstrText);?//?bstrText已經被釋放,應用是有問題的

每日一道理
一個安靜的夜晚,我獨自一人,有些空虛,有些凄涼。坐在星空下,抬頭仰望美麗天空,感覺真實卻由虛幻,閃閃爍爍,似乎看來還有些跳動。美的一切總在瞬間,如同“海市蜃樓”般,也只是剎那間的一閃而過,當天空變得明亮,而這星星也早已一同退去……

????::SysFreeString(bstrText);?//?這就不僅僅是重復釋放的問題了

????

????BSTR在類里面應用的誤區

????1、我想把某個[in]參數BSTR保存到某個類成員變量

????這類情況下,直接賦值是不行的,因為表面調用者會釋放這個BSTR參數,因此要保存的話,需要類函數自己重新申請一個新的BSTR

????void?CSomeClass::SetText(BSTR?bs)

????{

????//?m_bstrTextCSomeClass的成員變量

????m_bstrText?=?bs;?//?錯誤做法

????m_bstrText?=?::SysReAllocString(bs);?//?正確做法

????}

????

????2、我想傳出一個類的BSTR成員變量

????同樣的道理,因為表面可能在某個時間釋放傳出的BSTR變量,因此要防止類成員變量被無辜釋放,需要生成一個有效的拷貝,再傳出。

????void?CSomeClass::GetText(BSTR&?bs)

????{

????//?m_bstrTextCSomeClass的成員變量

????bs?=?m_bstrText;?//?錯誤做法

????bs?=?::SysAllocString(m_bstrText);?//?正確做法

????}

????

????BSTR的封裝類CComBSTR

????微軟發明我們應用BSTR有上面的各種不爽,因此決議對其停止封裝,很貼心吧!嗯,確實貼心,其中比擬好的一個封裝就是CComBSTR(很多項目組可能有自己的BSTR封裝,但是其實都是迥然不同的),這個封裝類確實很好用(雖然沒有供給CString那么多牛皮的功能),應用很方便,但是,如果我們錯誤應用也會發生噩夢,而且錯誤很難查找,我們來點評幾個(注意:下面的內容需要對CComBSTR封裝的基本原理和供給接口有必定了解,但這些并非本文要討論的內容,另外一個封裝類是_bstr_t,它是用引用計數來管理的,實現比CComBSTR復雜很多,個人不太建議應用_bstr_t)。

????1、被調用者違背out參數應用約定

????void?GetText(/*[out]*/BSTR&?bstrText)

????{

????CComBSTR?bstrT(_T("qqpcmgr"));

????//?錯誤:bstrT會被自動釋放,違背了out參數的應用約定

????bstrText?=?(BSTR)bstrT;

????return;

????

????//

????//?正確的做法,一般來講Detach是效率更好的方法

????//?但是如果bstrT本身是一個類成員變量,可能要用Copy

????bstrText?=?bstrT.Copy();

????????bstrText?=?bstrT.Detach();

????return;

????}

????

????2、調用者違背out參數應用約定

????void?GetText(/*[out]*/BSTR&?bstrText)

????{

????//?……

????}

????//?use?GetText

????CComBSTR?bstrText(L"qq");

????//?內存泄漏,調用GetText前要先清空bstrText

????//?bstrText.Empty();

????GetText(bstrText);

????

????3、看一個費解一點的

????void?GetText(/*[out]*/BSTR&?bstrText)

????{

????//?……

????}

????//?use?GetText

????CComBSTR?bstrText;

????BSTR?bstrInfo?=?NULL;

????GetText(bstrInfo);

????//?如果后面沒有表現釋放bstrInfo

????//?這里就會有內存泄漏,這類混用也是比擬危險的

????bstrText?=?bstrInfo;

????//?如果你想CComBSTR接管一個BSTR,可以應用

????//?bstrText.Attach(bstrInfo);

????

????4、重復釋放,造成內存損壞

????{

????CComBSTR?bstrText(L"Tencent");

????//?因為CComBSTR重載了operator?BSTR操作,因此這里是支持的

????::SysFreeString(bstrText);?//?錯誤做法,如果你確實想釋放,可以調用Empty

????}

????//?超越bstrText范圍,bstrText會被自動釋放,可能致使內存損壞

????//?……

????

????參考文獻

????[1]?BSTR?https://zh.wikipedia.org/zh-cn/BSTR

????[2]?BSTR_INSIDE?http://wenku.baidu.com/view/d577a1c5d5bbfd0a795673b2.html

????

文章結束給大家分享下程序員的一些笑話語錄: 現在社會太數字化了,所以最好是有一個集很多功能于一身的設備!

--------------------------------- 原創文章 By
釋放和參數
---------------------------------

轉載于:https://www.cnblogs.com/xinyuyuanm/archive/2013/05/30/3108990.html

總結

以上是生活随笔為你收集整理的释放参数BSTR使用误区以及隐藏的内存破坏和内存泄漏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。