函數參數傳遞的是指針的副本(按值傳遞)。函數內修改副本指向的內存內容有效,修改副本本身指向對調用者無效。
| 方式 | 代碼 | 結果 | 原理 |
|---|---|---|---|
| 直接賦值 ❌ | mallo = "bag"; | 失效 | 修改局部指針副本指向字符串常量區,返回後銷毀 |
| 逐字符賦值 ✅ | *(mallo++) = 'a'+rand()%26; | 生效 | 解引用寫入調用者分配的堆內存 |
| 臨時指針賦值 ✅ | char *t=mallo; *(t++) = ...; | 生效 | 保護原指針值,邏輯更清晰 |
| strcpy ✅ | strcpy(mallo, "bag"); | 生效 | 庫函數逐字節拷貝含\0結束符 |
調用者棧幀 被調用者棧幀 堆區
┌─────────────┐ ┌─────────────┐ ┌─────────────────┐
│ mallo ──────┼────►│ mallo (副本)│────►│ 36 bytes heap │
└─────────────┘ └─────────────┘ └─────────────────┘
▲ │
│ │
└──────── 修改*內容 可見 ──────────────┘
▲
│
└──────── 修改指針本身 不可見 ─────────┘
#include
#include
#include
void memtest(char *mallo) {
// strcpy(mallo, "bag"); // 方式4:生效
// mallo = "bag"; // 方式1:失效!
for (int i=0; i<36; i++) // 方式2:生效
mallo[i] = 'a' + rand()%26;
}
int main() {
char *mallo = malloc(36);
printf("Before: %s\n", mallo); // 亂碼
memtest(mallo);
printf("After: %s\n", mallo); // 隨機字母串
free(mallo);
return 0;
}
T*時,函數內只能修改*內容,不能修改指針本身T**(二級指針)或返回新指針strcpy/strncpy/snprintf<string.h>確保庫函數聲明可見