日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
論C/C++函數(shù)間動態(tài)內(nèi)存的傳遞

當你涉及到C/C++的核心編程的時候,你會無止境地與內(nèi)存管理打交道.這些往往會使人受盡折磨.所以如果你想深入C/C++編程,你必須靜下心來,好好苦一番.

創(chuàng)新互聯(lián)是專業(yè)的徐聞網(wǎng)站建設(shè)公司,徐聞接單;提供網(wǎng)站制作、成都做網(wǎng)站,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行徐聞網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!

現(xiàn)在我們將討論C/C++里我認為哪一本書都沒有完全說清楚,也是涉及概念細節(jié)最多,語言中最難的技術(shù)之一的動態(tài)內(nèi)存的傳遞.并且在軟件開發(fā)中很多專業(yè)人員并不能寫出相關(guān)的合格的代碼.

一、引入

看下面的例子,這是我們在編寫庫函數(shù)或者項目內(nèi)的共同函數(shù)經(jīng)常希望的.

 
 
  1. void MyFunc(char *pReturn, size_t size)
  2. {
  3. ……… 
  4. pReturn = (char *)malloc(sizeof(char) * num);
  5. ………
  6. }

我們可以很明顯地看出代碼作者的意圖,他想在函數(shù)調(diào)用處聲明一個指針 char *pMyReturn=NULL;然后調(diào)用MyFunc處理并返回一段長度為size的一段動態(tài)內(nèi)存.

那么作者能達到預(yù)期的效果嗎?

那么我可以告訴作者,他的程序在編譯期很幸運地通過了,可是在運行期他的程序崩潰終止.原因何在,是他觸犯了系統(tǒng)不可侵犯的條款:錯誤地操作內(nèi)存.

二、內(nèi)存操作及問題相關(guān)知識點

為了能徹底解決動態(tài)內(nèi)存?zhèn)鬟f的問題,我們先回顧一下內(nèi)存管理的知識要點.

(1)內(nèi)存分配方式有三種:

  • 從靜態(tài)存儲區(qū)域分配。內(nèi)存在程序編譯的時候就已經(jīng)分配好,這塊內(nèi)存在程序的整個運行期間都存在。例如全局變量,static變量。
  • 在棧上創(chuàng)建。在執(zhí)行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放。棧內(nèi)存分配運算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
  • 從堆上分配,亦稱動態(tài)內(nèi)存分配。程序在運行的時候用malloc或new申請任意多少的內(nèi)存,程序員自己負責在何時用free或delete釋放內(nèi)存。動態(tài)內(nèi)存的生存期由我們決定,使用非常靈活。

(2)指針的操作流程

申請并初始化或設(shè)置為空:

 
 
  1. int *pInt=NULL;

開辟空間或者使其指向?qū)ο?

 
 
  1. pInt=new Int(3);
  2. 或者
  3. int i=3;pint=&i;

用指針(更確切地說是操作內(nèi)存,在使用之前加if(pint!=NULL)或者assert(pInt!=NULL)后再使用,以防內(nèi)存申請失敗的情況下使用指針):

 
 
  1. if(p!=NULL) {use pint};

釋放使用完的內(nèi)存.

 
 
  1. free(pInt);

置指針為空

 
 
  1. pInt=NULL;(避免野指針的出現(xiàn))

(3) 在函數(shù)的參數(shù)傳遞中,編譯器總是要為函數(shù)的每個參數(shù)制作臨時副本,如果參數(shù)為p的話,那么編譯器會產(chǎn)生p的副本_p,使_p=p; 如果函數(shù)體內(nèi)的程序修改了_p的內(nèi)容,就導(dǎo)致參數(shù)p的內(nèi)容作相應(yīng)的修改。這就是指針可以用作輸出參數(shù)的原因.

三、問題分析

根據(jù)上面的規(guī)則我們可以很容易分析例子中失敗的原因.

 
 
  1. void MyFunc(char *pReturn, size_t size)
  2. {
  3. ……… 
  4. pReturn = (char *)malloc(sizeof(char) * num);
  5. ………
  6. }
  7. void main(void){
  8. char *pMyReturn=NULL;
  9. MyFunc(pMyReturn,10);
  10. }

在MyFunc(char *pReturn, size_t size)中_pMyReturn真實地申請到了內(nèi)存, _pMyReturn申請了新的內(nèi)存,只是把_pMyReturn 所指的內(nèi)存地址改變了,但是pMyReturn絲毫未變。所以函數(shù)MyFunc并不能輸出任何東西。事實上,每執(zhí)行一次MyFunc就會泄露一塊內(nèi)存,因為沒有用free釋放內(nèi)存。

四、問題解決方案

函數(shù)間傳遞動態(tài)數(shù)據(jù)我們可以有三種解決方法.

方法一.如果我們是用C++編程,我們可以很方便地利用引用這個技術(shù).我也極力推薦你用引用,因為它會使你少犯一些錯誤.以下是一個例子.

 
 
  1. void MyFunc(char* &pReturn,size_t size){
  2. pReturn=(char*)malloc(size);
  3. memset(pReturn,0x00,size);
  4. if(size>=13)
  5. strcpy(pReturn,"Hello World!");
  6. }
  7. void main(){
  8. char *pMyReturn=NULL;
  9. MyFunc(pMyReturn,15);
  10. if(pMyReturn!=NULL)
  11. {
  12. char *pTemp=pMyReturn;
  13. while(*pTemp!=''\0'')
  14. cout<<*pTemp++;
  15. pTemp=NULL;
  16. strcpy(pMyReturn,"AAAAAAAA");
  17. free(pMyReturn);
  18. pMyReturn=NULL;
  19. }
  20. }

方法二.利用二級指針

 
 
  1. void MyFunc (char ** pReturn, size_t size)
  2. {
  3. * pReturn = (char *)malloc(size);
  4. }
  5. void main(void)
  6. {
  7. char * pMyReturn = NULL;
  8. MyFunc (&pMyReturn, 100);// 注意參數(shù)是 & pMyReturn
  9. if(pMyReturn!=NULL){
  10. strcpy(pMyReturn, "hello");
  11. cout<< pMyReturn << endl;
  12. free(pMyReturn); 
  13. pMyReturn=NULL;
  14. }}

為什么二級指針就可以了.原因通過函數(shù)傳遞規(guī)則可以很容易地分析出來.我們將& pMyReturn傳遞了進去,就是將雙重指針的內(nèi)容傳遞到了函數(shù)中.函數(shù)過程利用改變指針的內(nèi)容,這樣pMyReturn很明顯指向了開辟的內(nèi)存 .

方法三. 用函數(shù)返回值來傳遞動態(tài)內(nèi)存

 
 
  1. char * MyFunc (void)
  2. {
  3. char *p =new char[20];
  4. memset(p,0x00,sizeof(p));
  5. return p;
  6. }
  7. void main(void)
  8. {
  9. char *str = NULL;
  10. str = MyFunc();
  11. if(str!=NULL)
  12. {
  13. strcpy(str,"Hello,baby");
  14. cout<< str << endl;
  15. free(str);
  16. str=NULL;
  17. }
  18. }

請注意的是函數(shù)寫成這樣的話,你是不能返回什么動態(tài)內(nèi)存的,因為p指向的是字符串常量.內(nèi)存在位于靜態(tài)存儲區(qū)
上分配,你無法改變.(你想要得到動態(tài)內(nèi)存我們一定要看到malloc或者new).

 
 
  1. char * MyFunc (void)
  2. {
  3. char *p =”Hello World”
  4. return p;
  5. }

結(jié)束語

操作內(nèi)存是C/C++一個難點,我們作為專業(yè)的軟件開發(fā)人員.應(yīng)該深入理解并能靈活地掌握指針和內(nèi)存的操作.


標題名稱:論C/C++函數(shù)間動態(tài)內(nèi)存的傳遞
標題來源:http://www.5511xx.com/article/coidcps.html