malloc 導致內存洩漏典型案例
char *name = malloc(20);
name = "abcdef"; // 錯誤:name 丟失堆地址,指向常量區,20 字節洩漏
// 正確:
strcpy(name, "abcdef"); // 或 strncpy
聯合體特性
- 所有成員共享同一塊內存,大小 = 最大成員大小
- 任一時刻只有一個成員有效值
- 不可初始化定義 (C99 允許指定初始化器)
- 同類型聯合體可整體賦值
- 最後存入的成員決定當前解釋方式
union { short i; char c; } u;
u.i = 0x0041; // 65+256=321
u.c; // 取低字節 0x41 = 65 (小端機)
內存分配函數對比
| 函數 | 初始化 | 重分配行為 |
| malloc | 不初始化 (垃圾值) | - |
| calloc | 歸零 | - |
| realloc | 保留原數據,新增部分未初始化 | 可能移動內存塊,返回新指針 |
結構體對齊規則
- 成員按聲明順序排列,各自按其類型對齊 (通常 4/8 字節)
- 結構體整體大小為最大成員對齊數的倍數 (尾部填充)
#pragma pack(n) 可改變對齊模數
struct { char c; int i; }; // 大小 8: c(1) + 3填充 + i(4)
struct { int i; char c; }; // 大小 8: i(4) + c(1) + 3填充
NULL 在 C/C++ 中的定義差異
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif
C++ 不允許 void* 隱式轉換,故用 0 或 nullptr (C++11)。
valgrind 檢查內存洩漏
valgrind --tool=memcheck --leak-check=full ./a.out
umask 權限掩碼
umask 022 → 新文件默認權限 666 & ~022 = 644,目錄 777 & ~022 = 755。對應位清零表示去除該權限。
判斷無符號類型宏
#define IS_UNSIGNED(type) ((type)0 - (type)1 > 0)
// 原理:無符號 0-1 回繞為最大值 > 0
sizeof 經典陷阱
void func(char str[50]) {
sizeof(str); // 4/8 (指針大小),非 50!參數退化為指針
}
char s[50] = "abc";
sizeof(s); // 50 (數組大小,含 \0)
char *p = s;
sizeof(p); // 指針大小
sizeof(*p); // 1 (char)
sizeof(p++); // 指針大小,p 不會真正遞增 (sizeof 不求值)
字符串長度與 sizeof
char stra[] = "HelloWorld"; // 大小 11 (含 \0)
char *strb = stra;
strlen(strb); // 10
strlen(strb++); // 參數求值順序未定義,慎用
sizeof(stra); // 11
sizeof(strb++); // 指針大小 (4/8),strb 不變
- 上一篇文章: Windows 驅動開發核心 API 速查:DriverEntry、設備創建、符號鏈接與清理
- 下一篇文章: C語言指標專題:從基礎到進階的完整教學代碼集
Copyright ©
程式碼之家 All Rights Reserved