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

C 語言鏈表實現錯誤分析:結構體直接轉換導致數據覆蓋

     編輯:程式設計綜合問答

核心錯誤

typedef struct _Teacher { int age; } Teacher;
Teacher t1 = {100};
LinkList_insert(list, 0, (LinkListNode*)(&t1)); // 強制轉換!

問題本質

Teacher 結構體內存佈局:[age: 4 bytes]。
LinkListNode 佈局:[next: 8 bytes (指針)]。
強制轉換將 &t1 當作 LinkListNode*,插入鏈表時:

  • 鏈表操作寫入 node->next(偏移 0,8 字節),直接覆蓋 t1.age 及後續內存。
  • 讀取時 LinkList_get 返回節點指釖,轉回 Teacher* 讀取 age,實際讀到的是 next 指針的低位部分(通常為 0)。

正確設計:侵入式 vs 非侵入式

方案一:非侵入式(推薦通用)

typedef struct _LinkListNode {
    struct _LinkListNode *next;
    void *data;  // 存儲用戶數據指針
} LinkListNode;

// 插入
LinkListNode *node = malloc(sizeof(LinkListNode));
node->data = &t1; // 或 malloc 複製數據
node->next = NULL;
LinkList_insert(list, pos, node);

// 讀取
LinkListNode *n = LinkList_get(list, 0);
Teacher *tp = (Teacher*)n->data;
printf("%d", tp->age);

方案二:侵入式(Linux 內核風格)

typedef struct _Teacher {
    int age;
    LinkListNode node; // 內嵌節點,必須為第一個成員
} Teacher;

// 使用 container_of 宏獲取外層結構體
#define container_of(ptr, type, member) ((type*)((char*)(ptr) - offsetof(type, member)))

Teacher t1 = {100, {NULL}};
LinkList_insert(list, 0, &t1.node);

// 讀取
LinkListNode *n = LinkList_get(list, 0);
Teacher *tp = container_of(n, Teacher, node);

代碼修正要點

  1. LinkListNode 增加 void *data 或改為侵入式設計。
  2. LinkList_create 初始化 head->data = NULL。
  3. main 中創建獨立節點,關聯數據指針。
  4. LinkList_clear 遞歸釋放節點及數據(若動態分配)。

修正後 main 示例

int main() {
    Teacher t1={100}, t2={2}, t3={3};
    LinkListNode n1={NULL,&t1}, n2={NULL,&t2}, n3={NULL,&t3};
    Link *list = LinkList_create();
    LinkList_insert(list, 0, &n1);
    Teacher *tp = (Teacher*)LinkList_get(list, 0)->data;
    printf("%d\n", tp->age); // 100
    LinkList_insert(list, 1, &n2);
    LinkList_insert(list, 2, &n3);
    // 遍歷打印
    for (int i=0; i<3; i++) {
        Teacher *t = (Teacher*)LinkList_get(list, i)->data;
        printf("%d ", t->age);
    }
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved