首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言鏈隊列初始化存取違規:指標未分配記憶體就解參考

     編輯:程式設計疑難解答

錯誤代碼片段

int initLqueue(Lqueue **q) {
    if (((*q)->front = (Qnodetype*)malloc(sizeof(Qnodetype))) == NULL) return FALSE;
    (*q)->rear = (*q)->front;
    strcpy((*q)->front->data, "head");
    (*q)->front->next = NULL;
    (*q)->number = 0;
    return TRUE;
}

錯誤現象

呼叫 initLqueue(&Lp) 時,Lp 為未初始化的區域指標變數(野指標)。函式內直接對 *q 解參考並存取 ->front,導致存取違規。

根本原因

Lqueue *Lp; 僅宣告指標,未指向有效記憶體。傳遞 &Lp 給函式後,q 指向該指標變數,但 *q(即 Lp)的值是隨機位址,隨即對隨機位址寫入 front 成員造成崩潰。

修正方式:在呼叫端先分配結構體記憶體

void main() {
    Lqueue *Lp = (Lqueue*)malloc(sizeof(Lqueue));  // 先分配 Lqueue 結構體
    if (!Lp) return;
    
    initLqueue(&Lp);  // 傳遞指標的位址
    // ... 後續邏輯
    
    // 程式結束前釋放所有節點與 Lp
}

替代設計:讓 initLqueue 內部分配並回傳指標

Lqueue* initLqueue() {
    Lqueue *q = (Lqueue*)malloc(sizeof(Lqueue));
    if (!q) return NULL;
    
    q->front = (Qnodetype*)malloc(sizeof(Qnodetype));
    if (!q->front) { free(q); return NULL; }
    
    q->rear = q->front;
    strcpy(q->front->data, "head");
    q->front->next = NULL;
    q->number = 0;
    return q;
}

// 呼叫
Lqueue *Lp = initLqueue();

完整記憶體管理提醒

  • 每個 malloc 必須配對 free,包含佇列節點、頭節點與 Lqueue 本體。
  • 建議撰寫 destroyLqueue(Lqueue **q) 統一釋放所有資源。
  • 使用 Valgrind / AddressSanitizer 偵測記憶體洩漏與非法存取。

總結

「存取位置衝突」源於對未分配記憶體的指標解參考。修正核心在於**先為 Lqueue 結構體分配記憶體**,再傳遞其位址給初始化函式,或改由初始化函式負責分配並回傳指標。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved