sizeof 可計算陣列容量(位元組數)。
char a[] = "hello world"; → sizeof(a) = 12(含 \0)。char* p = a; → sizeof(p) = 4(32 位元系統指標大小),非 p 所指記憶體大小。C/C++ 無法從指標得知所指記憶體大小,除非配置時記住它。
void Func(char a[100]) {
cout << sizeof(a) << endl; // 輸出 4,而非 100!
}
無論宣告 char a[100] 或 char a[],參數傳遞時一律退化為 char*,sizeof 只能得知指標大小。
錯誤示範:嘗試在函式內用指標參數配置動態記憶體:
void GetMemory(char* p, int num) {
p = (char*)malloc(sizeof(char) * num); // 只修改區域副本 _p
}
void Test() {
char* str = NULL;
GetMemory(str, 100); // str 仍為 NULL
strcpy(str, "hello"); // 執行期錯誤
}
原因:編譯器為參數建立區域副本 _p,_p = p。函式內修改 _p 指向新記憶體,不影響外部 p。且每次呼叫洩漏一塊記憶體(未 free)。
void GetMemory2(char** p, int num) {
*p = (char*)malloc(sizeof(char) * num);
}
void Test2() {
char* str = NULL;
GetMemory2(&str, 100); // 傳遞 &str
strcpy(str, "hello");
cout << str << endl;
free(str);
}
char* GetMemory3(int num) {
char* p = (char*)malloc(sizeof(char) * num);
return p;
}
void Test3() {
char* str = GetMemory3(100);
strcpy(str, "hello");
cout << str << endl;
free(str);
}
char* GetString() {
char p[] = "hello world"; // 位於堆疊
return p; // 編譯器警告:回傳區域變數位址
}
void Test4() {
char* str = GetString(); // str 內容為垃圾
cout << str << endl;
}
區域陣列 p 在函式結束時自動銷毀,回傳其位址屬未定義行為。
char* GetString2() {
char* p = "hello world"; // 常數字串在靜態區
return p;
}
執行不出錯,但設計錯誤:GetString2 總是回傳同一塊唯讀靜態記憶體,呼叫端若嘗試修改會崩潰。