函數需返回字符串時,三大策略:堆分配(調用者釋放,易漏/重釋)、調用者傳緩衝區(最安全)、返回內部 static 緩衝區(介面漂亮但暗藏殺機)。
char *inet_ntoa(struct in_addr in) 內部用 static char[] 返回 IP 字符串。調用示例:
struct in_addr src, des;
// ...
fprintf(fp, "源IP<%s> 目的IP<%s>\n", inet_ntoa(src), inet_ntoa(des));
現象:源/目的 IP 輸出完全相同。原因:參數求值順序中,第二次調用覆蓋了靜態緩衝區,兩個 %s 指向同一地址、同一內容。man page 明確警告:「返回靜態緩衝區,後續調用將覆蓋」。
if (strcmp(inet_ntoa(ip1), inet_ntoa(ip2)) == 0) { ... }
// 永真!因兩次調用返回同一緩衝區地址
《Effective C++》條款 23 亦否定返回函數內部 static 對象引用,觀點一致。