void GetMemory(char *p, int num) { p = (char*)malloc(sizeof(char)*num); }
void Test() { char *str=NULL; GetMemory(str,100); strcpy(str,"hello"); } // str 仍為 NULL,崩潰
原因:參數 p 是指標的副本,函數內修改 p 指向的新記憶體,不影響外部 str。且每次呼叫洩漏記憶體。
void GetMemory2(char **p, int num) { *p = (char*)malloc(sizeof(char)*num); }
void Test2() { char *str=NULL; GetMemory2(&str,100); strcpy(str,"hello"); free(str); }
傳遞 &str,函數透過解參考修改原指標指向。
char *GetMemory3(int num) { return (char*)malloc(sizeof(char)*num); }
void Test3() { char *str = GetMemory3(100); strcpy(str,"hello"); free(str); }
語意清晰、呼叫端直觀,避免雙重指標複雜度。
char *GetString() { char p[]="hello world"; return p; } // 錯誤:p 在棧上,函數返回即銷毀
除錯器可見 str 非 NULL 但內容為亂碼。
char *GetString2() { return "hello world"; } // 常數區,生命週期全程
雖能執行,但設計概念錯誤:回傳唯讀記憶體,呼叫端不可修改,且多次呼叫回傳同一地址。
** 或回傳值。