首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言學習筆記 (四):內存洩漏、聯合體、內存分配、結構體對齊、NULL 定義、valgrind 與 sizeof 陷阱

     編輯:關於C語言

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 (小端機)

內存分配函數對比

結構體對齊規則

  • 成員按聲明順序排列,各自按其類型對齊 (通常 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 不變
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數初始化重分配行為
malloc不初始化 (垃圾值)-
calloc歸零-
realloc保留原數據,新增部分未初始化可能移動內存塊,返回新指針