這次我們談談七大讓工程師黯然消魂的問題中排名第七的問題, 外號 -- “吸星大法"
嵌入式程式開發人員一般來說,
會使用使用系統預設提供的API 來進行取得(allocate) 和釋放(free) heap memory的工作
例如下面的程式碼
void some_function(void) {
int*pi;
pi = (int *) os_malloc_b(sizeof(int));
/*do something for pi */
os_mfree(pi);
}
這個例子中, os_malloc_b() 是allocate memory 的 API,
而 os_mfree() 是free memory 的 API
但是有時候 allocate memory 的方式不是那麼直覺的,(例如自以為是的架構長直接下令統一風格)
而是透過Macro 來allocate memory,
看下面這個範例
#define OS_ALLOC_MSG_PTR(p, type) \
P = (type *) os_malloc_b(sizeof(type))
#define OS_FREE_MSG(p) os_mfree(p)
boolean memory_leak_function(void) {
T_MSG*pMsg;
OS_ALLOC_MSG_PTR(pMsg,T_MSG); //1
/* fill some data in the message */
if (os_send_msg(Task_A,pMsg) < 0 ) { //2
return false; //3
}
}
這段程式在 //1 的地方用 Macro allocate 一塊memory 用來當作送出去的message ,
然後在//2 呼叫 os_send_msg 送給 Task A,
由 Task A 處理完畢之後,
free 掉這塊收到的 message
這段程式乍看之下沒有錯 (但是天底下哪有這麼好的事情)
主要會發生的問題是//2 send message 的時候可能有失敗的情形, (誰叫你們用的CPU處理速度這麼慢)
大多數的程式開發人員都會記得處理錯誤的case , (如果連這個都沒處理, 就應該拖出午門斬首)
例如 //3
但是會忘記 free 掉原先那塊不用的memory.(因為不會馬上死人, 所以這個問題很難被抓到)
這樣系統就會久久當一次機(因為 memory 不夠用), 成為懸而未解的問題
正確的寫法如下,
增加 //4, 釋放掉memory 再回error code.
if (os_send_msg(Task_A,pMsg) < 0 ) {
OS_FREE_MSG(pMsg); //4
return false;
}
}
沒有留言:
張貼留言