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

C 語言指標陷阱:未分配記憶體直接解參考導致崩潰

     編輯:關於C語言

錯誤程式碼

struct person { int age; char name; };
struct student { struct person abc; int id; };

struct student *f1;  // 僅宣告指標,未分配記憶體!

int main()
{
    f1->id = 20;           // 段錯誤:寫入隨機位址
    f1->abc.age = 20;      // 未定義行為
    return 0;
}

錯誤分析

  • f1 是野指標,值為隨機堆疊殘留資料
  • 解參考 f1->id 相當於 *(f1 + offset),存取非法記憶體
  • 作業系統偵測到非法存取,送出 SIGSEGV,程式終止

正確程式碼

int main()
{
    struct student *f1 = malloc(sizeof(struct student));
    if (!f1) { perror("malloc"); return 1; }

    f1->id = 20;
    printf("%d\n", f1->id);

    f1->abc.age = 20;
    printf("%d\n", f1->abc.age);

    free(f1);  // 釋放記憶體,良好習慣
    f1 = NULL; // 避免懸空指標
    return 0;
}

記憶體分配檢查清單

情境正確做法
結構體指標malloc(sizeof(Struct))
陣列指標malloc(n * sizeof(Type))
字串malloc(strlen(src) + 1)
嵌套結構體外層 malloc 即可,內層隨外層分配
釋放每個 malloc 對應一個 free,釋放後置 NULL

進階技巧:柔性陣列成員 (C99)

struct buffer {
    size_t len;
    char data[];  // 柔性陣列,不佔結構體大小
};

struct buffer *buf = malloc(sizeof(struct buffer) + 100);
buf->len = 100;
// buf->data 可直接使用 100 bytes
free(buf);  // 一次釋放全部

除錯工具

  • valgrind --leak-check=full ./prog:偵測記憶體洩漏、非法存取
  • gcc -fsanitize=address -g:AddressSanitizer 編譯期插桩
  • malloc.h 的 mtrace():追蹤 malloc/free 呼叫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved