未經許可,不的轉載
版權歸屬高雷個人
聯絡方式:
email:gaolei57521@gamil.com
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行程式碼太麻煩了,可以定一個巨集
如果行用一個函式來釋放並且達到同樣的目的該如何寫呢?
- //釋放指標型別資料
- void freePointer(void *p)
- {
- if( p != NULL )
- {
- free( p );
- p = NULL;
- }
- }
這麼寫是不行的,因為指標p是通過copy方式將實參的值copy過來,
free( p ); 沒問題,可以把指標p所指的記憶體釋放,但取無法把指標指向NULL,這是因為形參的地址和實參的地址是不同的!
- //釋放指標型別資料
- void freePointer(void **p)
- {
- if( *p != NULL )
- {
- free( *p );
- *p = NULL;
- }
- }
這樣修改就可以了,但這要求實引數是一個指標的地址
使用的時候要這麼用
freePointer( (void *)(&pRole) );
這樣用著依然不爽,強制型別轉換有些編譯器是必須的,比如我用的,
基本不是,取指標地址還是必須的!總之給人不直觀,不清爽的感覺,
如果換成
FREE( pRole );
就好多了!
1.1如果釋放一個帶有指標的結構體指標
- //角色資料型別
- typedef struct
- {
- char* name; //動作檔案的名字
- }ACT; //動畫
- typedef struct
- {
- ACT* body; //身體動作資料
- }Role;
建立角色物件,我想通過一個方法
- // 建立 角色資料物件
- Role* creatRole( const char* roleName, uint8 weaponId );
- // 回收 角色資料物件
- void destroyRole( Role *role);
那麼建立的時候確實可以得到一個角色的指標
Role *pRole =creatRole( “hero”, 0 );
釋放的時候如果想達到呼叫
destroyRole(pRole );
後,pRole 指向NULL,該如何做呢?
通過freePointer()方法給我們的教訓可以知道,
- /* 回收 角色資料物件 */
- 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()物件,在除錯的時候是看不出來的!
另外還要提到一點
- 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.未經許可 不得轉載!