寫韌體寫久了,有些東西會變成肌肉記憶,手就是會自動打出來。指標宣告完順手 = NULL,這大概是每個 C 工程師的本能反應。
但前陣子在 debug 一個詭異的 crash,追了大半天才發現:問題出在我對 NULL、0、和「指標初始化」這幾件事的理解,其實一直有個模糊地帶。
事情是怎麼開始的
在一個專案裡,有一段大概長這樣的 code:
struct sensor_ctx {
uint8_t *buf;
uint16_t len;
int (*callback)(uint8_t *data, uint16_t size);
};
void sensor_init(struct sensor_ctx *ctx)
{
memset(ctx, 0, sizeof(*ctx));
// 後面根據設定去 assign buf 和 callback
}
看起來超正常對吧?memset 把整個 struct 清成 0,指標欄位自然就是 NULL,之後再根據需要 assign。
這段 code 在我們的 ARM Cortex-M4 平台跑了好幾個月都沒事。直到有一天,同事把類似的邏輯搬到另一個比較冷門的平台上——然後 callback 呼叫就莫名 crash 了。