未經許可,不的轉載
版權歸屬高雷個人
聯系方式:
email:[email protected]
qq:38929568
由於本人剛剛編寫C程序不久,文章中不當的地方難免會有,望大家批評指正,我會第一時間修改!
最近搞MTK游戲開發,使用的是C語言,所以想研究一下C語言的開發情況,通過論壇,或者搜索到一些高手的文章,給我的啟示不小!結合以前的Java經驗,想總結一下,高手都是如何寫程序的...
我的文章不會講述一個C語言學習的過程,也不會面面俱到講述C語言,我只針對學習過C語言,或者有一定編程基礎,在寫代碼的時候總是不自信地想知道別人是如何編寫的!
我希望通過閱讀本文,能夠使初級程序員迅速成長為高級程序員!
1.如何釋放內存
很簡單free();就ok啦!
C語言中,malloc,realloc,calloc,strdup等等都是動態從堆裡面分配的內存,他不會自動釋放。在這裡需要記錄分配的地址,以便以後釋放。如果不進行釋放,會造成內存洩漏。在堆內存申請的內存是需要程序員管理的,系統不會主動回收,可以通過free()函數回收。通常的商業代碼都有很多指針,或者指針的指針,結構體裡包含指針類型的成員,那麼這些指針該如何管理,才不至於出錯呢?
例如 Role *pRole = (Role *)malloc( sizeof(Role) );
釋放指針
free( pRole );
pRole = NULL;
釋放指針後,將指針指回0點,如果你覺得每次都要寫2行代碼太麻煩了,可以定一個宏
/* * 釋放指針類型數據,直接使用內存指針變量 */ #define FREE(X) \ do{ \ if( (X) != NULL ) \ { \ free( (void *)(X) ); \ (X)=NULL; \ } \ }while(0)
如果行用一個函數來釋放並且達到同樣的目的該如何寫呢?
view plaincopy to clipboardprint?
//釋放指針類型數據 void freePointer(void *p) { if( p != NULL ) { free( p ); p = NULL; } }
這麼寫是不行的,因為指針p是通過copy方式將實參的值copy過來,
free( p ); 沒問題,可以把指針p所指的內存釋放,但取無法把指針指向NULL,這是因為形參的地址和實參的地址是不同的!
view plaincopy to clipboardprint?
//釋放指針類型數據 void freePointer(void **p) { if( *p != NULL ) { free( *p ); *p = NULL; } }
這樣修改就可以了,但這要求實參數是一個指針的地址
使用的時候要這麼用
freePointer( (void *)(&pRole) );
這樣用著依然不爽,強制類型轉換有些編譯器是必須的,比如我用的,
基本不是,取指針地址還是必須的!總之給人不直觀,不清爽的感覺,
如果換成
FREE( pRole );
就好多了!
1.1如果釋放一個帶有指針的結構體指針
view plaincopy to clipboardprint?
//角色數據類型 typedef struct { char* name; //動作文件的名字 }ACT; //動畫 typedef struct { ACT* body; //身體動作數據 }Role;
創建角色對象,我想通過一個方法
view plaincopy to clipboardprint?
// 創建 角色數據對象 Role* creatRole( const char* roleName, uint8 weaponId ); // 回收 角色數據對象 void destroyRole( Role *role);
那麼創建的時候確實可以得到一個角色的指針
Role *pRole =creatRole( "hero", 0 );
釋放的時候如果想達到調用
destroyRole(pRole );
後,pRole 指向NULL,該如何做呢?
通過freePointer()方法給我們的教訓可以知道,
view plaincopy to clipboardprint?
/* 回收 角色數據對象 */ void destroyRole( Role *role ) { if( role == NULL ) return; destroyAct( role->body );//是否結構體內的指針,有幾個就要釋放幾個 free( role ); role = NULL; }
其中的role = NULL;是不能把實參pRole 指向NULL的!
如果我們向前面提到那樣使用宏,或者獲取指針地址的形式似乎可以解決,但其實沒必要那麼麻煩,通常的做法是手動指向NULL
destroyRole(pRole );
pRole = NULL;
為什麼要有pRole = NULL;這句呢?因為最上層的結構體對象通常都是需要程序知道是否
為空,或者非空,另外指回原點,也對調試有好處,單獨free()對象,在調試的時候是看不出來的!
另外還要提到一點
view plaincopy to clipboardprint?
Role* creatRole( const char* roleName, uint8 weaponId ) { Role role; role.body= (ACT*)malloc( sizeof(ACT) ); return &role; }
這個方法是絕對不可取的,因為role是函數內部的臨時變量,在函數結束的時候會被系統回收的,隨意&role這個地方的數據將被系統重新使用。
在C語言編程中並不是所有指針都需要指回NULL的,如果你願意都指回NULL更好,但至少應該把一組指針的源頭指回NULL,這才能防止程序出錯,另外就是把源頭指回NULL之前要確保該指針下面的全部指針都已經被回收了!否則就內存洩漏了!
PS.未經許可 不得轉載!
本文出自 “鍵碼視窗” 博客,謝絕轉載!