數組和鏈表safe

 數組

數組是需要使用連續內存時候申請的一種內存,int a[10],聲明定義必須制定大小

int a[]可作爲參數傳入是代表a的首地址

訪問數組內的數據:a[1]下表方式,其實也是一個地址取值,去a+1的地址上取值*(a+1)

一個數據+1代表,地址後移數據的類型大小sizeof(a)

連續內存申請:

 結構體中的最後一個元素爲int buf[0],這時候buf是不佔內存大小的

當malloc申請大於結構體本身內存大小時候,buf就可以指向了後臺多餘內存的地址和類型

鏈表

鏈表用於不定長的不連續內存的申請

不定長:每加一個元素都是看時機的,所以每次都要malloc

不連續,每次malloc的時候只是一個元素,和前面元素不連續,就需要一根線連起來,不然我們就把前面的元素弄丟了

struct list {

    struct list *prev,*next;

};

鏈表僅是一根線,線上有自己的數據類型mydata

struct mylist {

    void *mydata;

    struct list;

};

還需要解決的問題:添加一個,刪除一個,遍歷查找數據

struct inline void __list_add(struct list  *new, struct list  *prev, struct list  *next)
{
    next->prev = new;
    new->next = next;
    new->prev = prev;
    prev->next = new;
}

添加需要知道新的數據地址,要添加的地方,

需要建立關係:前一數據的後,後一數據的前,新數據的前,新數據的後

struct inline void list_add(struct list  *new, struct list  *head)
{
    __list_add(new, head, head->next);
}

添加尾部,確定位置是鏈表頭的前一元素

struct inline void list_add_tail(struct list  *new, struct list  *head)
{
    __list_add(new, head->prev, head);
}

刪除一個元素,需要確定關係刪除數據的前面數據的後,刪除數據的後面數據的前

struct inline void __list_del(struct list  *prev, struct list *next)
{
    prev->next = next;
    next->prev = prev;
}

要刪除的元素需要鏈表賦值清零

struct inline void list_del(struct list  *entry)
{
    __list_del(entry->prev, entry->next);
    entry->next = (void *) 0;
    entry->prev = (void *) 0;
}

 

遍歷,從頭開始遍歷,到循環到頭停止

開始賦值,pos=head->next,這裏head沒有mydata

條件:pos!=head

執行動作:pos=pos->next

safe:刪除當前節點時候,執行動作會有空指針,所以需要n預先存儲pos->next

 

//CPU提供的 prefetch 指令將數據放入緩存
#define list_for_each(pos,head) \
for (pos = head->next, prefetch(pos->next); pos != head;\
    pos = pos->next, prefetch(pos->next))

#define list_for_each_prev(pos,head) \
for (pos = head->prev; pos != head; pos = pos->prev)
//因此只遍歷鏈表不刪除節點時可以使用前者,若有刪除節點的操作,則要使用後者


#define list_for_each_safe(pos, n, head) \
for (pos = head->next, n = pos->next; pos != head; pos = n, n = pos->next)

知道結構體內某一成員變量地址,求結構體地址
//上到下加法,下到上減法
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

type 0地址是結構體所在地址,那麼member就是絕對地址,member的相對地址ptr就可以求得結構體當前地址

#define container_of(ptr, type, member) ({          \
    const typeof(((type *)0)->member)*__mptr = (ptr);    \
             (type *)((char *)__mptr - offsetof(type, member)); })

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章