Linux内核链表原理

Linux内核链表??? 难道普通的链表不满足?,当然满足了 但是感觉缺少点对链表深刻了解的过程 普通链表结点 数据域 and 指针域 Lnux内核链表结点 指针域 只有指针域 那怎么放数据呢?? 通过结构体定义 链表结点元素 数据1,数据2... 数据n-1 定义多少个数据都可以 ,但是最后一个必须 为Lnux内核链表结点 变量或者指向堆内存空间 的指针 首先分析一下 为啥使用Linux内核链表 生活当中的 汽车和客车和高铁 民用客机,他们有一个共同的 特征:座椅 所谓的座椅 就是这些民用汽车和客车 高铁 民用客机就是这些 数据 也就是普通链表 货车 运煤炭的火车车箱底部是空的 就可以载人 或许有一定的危险性 开快了会直接 哦呐呐呐+ 黑人抬棺BGM ......脑补一下画面, 这些最好是拿来运一些煤炭,或者放一些集装箱 之类的 这有那个装箱子 , 这些就是底盘 数据放在另一个结构体里方便数据操作

  • 看看大概的样子
  • 大块的矩形 --- 数据
  • 两个合成的矩形 --- 结点
  • 这要包含这个小结点 就能访问 小结点 上面对的数据

Lnux内核链表结点变量

直接上C/C++ 代码

#include
using namespace std;

//Linux 共享 双向链表结点
using LinkNode = struct __DoubleLinkNode;

//Linux 共享 双向链表结点
struct __DoubleLinkNode {

    LinkNode* prev;
    LinkNode* next;
};

//Linux 共享 双向链表
struct __DoubleLinkList {
    LinkNode *List;
    size_t size;    
};

struct Student{
    char name[14];
    int age;
};

struct LinkElem{

    
    Student s;
    LinkNode node;
    
};

using LinkList = __DoubleLinkList;


void  initLinkList(LinkList& List,  LinkNode * const initList=nullptr) {

    List.List = new LinkNode{ initList, initList };
        
    List.size = 0u;
}

void Link(LinkNode*& node, LinkNode*& newnode) {

    if (node->next) {

        node->next->prev = newnode;
        newnode->next = node->next;
    }
    newnode->prev = node;
    node->next = newnode;
}

void LinkListInsert_back(LinkList& List, LinkNode*& Newnode) {

    LinkNode* current = List.List;
    while (current->next) {

        current = current->next;
    }

    Link(current, Newnode);
    ++List.size;
}

void LinkListDestroy(LinkList& List) {

    LinkNode* &iter = List.List;
    LinkNode*& iterNext = iter->next = iter->next->next = iter->next->prev = nullptr;
    
    delete iter;
    iter = iterNext=nullptr;

        
    List.size = (size_t)iter;
}


LinkElem* CreatorLinkElem(const size_t& size) {
    return  new LinkElem[size];
}

void LinkElemDestroy(LinkElem*&e) {

    
        delete[] e;
        e = nullptr;

}

int main(void) {
    
    
    LinkList List;
    
    initLinkList(List);

    size_t LinkElemArraySize = 26;
    LinkElem* e = nullptr;

    const char studentName[] = "ABCDEFGHIJKLMNOPQRTUVWXYZ\0";
    e = CreatorLinkElem(LinkElemArraySize);

    for (size_t i = 0; i < LinkElemArraySize; i++){
        
        strcpy_s(e[i].s.name, {"Student_"});

        strncat_s(e[i].s.name, &studentName[i], 1);

        const int age = LinkElemArraySize - 3;
        e[i].s.age = age % 18 + 13;
        e[i].node = LinkNode{nullptr};
        LinkNode*node =&e[i].node;

        LinkListInsert_back(List, node);
    }

    LinkNode* current = List.List->next;
    const size_t LinkElemNodeoffset = offsetof(LinkElem, node);

    while ((  current)->next){

        LinkElem*&& elemvalue = (LinkElem*)((size_t)current - (size_t)LinkElemNodeoffset);
        cout << " 学生姓名:" << elemvalue->s.name << "	学生年龄:" << elemvalue->s.age << endl;

        current = (current)->next;
    }

    LinkElemDestroy(e);
    LinkListDestroy(List);

        
    return 0;
}

源码解析: offsetof(LinkElem, node); 求node 在这个结构体偏移量 首先说明一下: 栈和堆 只要是顺序的内存空间都可以做链接成链表 ,不是顺序无法找到偏移量 栈是可以找到偏移量 ,堆就不可行

根据偏移量 找到的node结点 访问数据

Lnux内核链表结点指针

#include
using namespace std;

//Linux 共享 双向链表结点
using LinkNode = struct __DoubleLinkNode;

//Linux 共享 双向链表结点
struct __DoubleLinkNode {

    LinkNode* prev;
    LinkNode* next;
};

//Linux 共享 双向链表
struct __DoubleLinkList {
    LinkNode *List;
    size_t size;    
};

struct Student{
    char name[32];
    int age;

};
struct LinkElem{

    
    Student s;
    LinkNode *node;
    
};

using LinkList = __DoubleLinkList;


void  initLinkList(LinkList& List,  LinkNode * const initList=nullptr) {

    List.List = new LinkNode{ initList, initList };
        
    List.size = 0u;
}

void Link(LinkNode*& node, LinkNode*& newnode) {

    if (node->next) {

        node->next->prev = newnode;
        newnode->next = node->next;
    }
    newnode->prev = node;
    node->next = newnode;
}

void LinkListInsert_back(LinkList& List, LinkNode*& Newnode) {

    LinkNode* current = List.List;
    while (current->next) {

        current = current->next;
    }

    Link(current, Newnode);
    ++List.size;
}

void LinkListDestroy(LinkList& List) {

    LinkNode* &iter = List.List;
    LinkNode* iterNext = iter->next;
    delete iter;
    iter = iterNext;
    while (iter){
        iterNext = iter->next;
        iter->prev = nullptr;
        iter->next = nullptr;
        iter = iterNext;
    }
    iter = nullptr;
    
    List.size = (size_t)iter;
}


LinkElem* CreatorLinkElem(const size_t& size) {
    return  new LinkElem[size];
}

void LinkElemDestroy(LinkElem*& e) {

    delete[] e;
    e = nullptr;
}

int main(void) {
    
    
    LinkList List;
    
    initLinkList(List);

    size_t LinkElemArraySize = 26;
    LinkElem* e = CreatorLinkElem(LinkElemArraySize);

    const char studentName[] = "ABCDEFGHIJKLMNOPQRTUVWXYZ";

    for (size_t i = 0; i < LinkElemArraySize; i++){
        
        strcpy_s(e[i].s.name, { "Student_" });

        strncat_s(e[i].s.name, &studentName[i], 1);

        const int age = LinkElemArraySize;
        e[i].s.age = age % 18+13;
        e[i].node = new LinkNode;
        cout << "node 分配的地址为 " << e[i].node << endl;
        e[i].node->prev = nullptr;
        e[i].node->next = nullptr;
    }
    
    for (size_t i = 0; i < LinkElemArraySize; i++) {
        LinkNode*node = (e + i)->node;
        LinkListInsert_back(List, node);
    }


    LinkNode* current = List.List->next;
    size_t i = 0;
    while (current-?next){
        const LinkElem* eptr = e + i;
        //获取node 偏移量
        const size_t LinkElemNodeoffset = ((size_t)current - (size_t)eptr);

        LinkElem* elemvalue = (LinkElem*)((size_t)current - LinkElemNodeoffset);
        cout << " 学生姓名:" << elemvalue->s.name << "	学生年龄:" << elemvalue->s.age << endl;
        ++i;
        current = current->next;
    }
    LinkListDestroy(List);
    LinkElemDestroy(e);
        
    return 0;
}

注意事项:栈和堆 只要是顺序的内存空间都可以做链接成链表 ,不是顺序无法找到偏移量** 栈是可以的找到偏移量 ,** 堆就不可行

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章