C語言解譯器的實現–儲存結構(一)

來源:互聯網
上載者:User

上一篇:C語言解譯器的實現--序(零)

目錄:

     1. 記憶體池

     2. 棧

     3. Hash表

1.記憶體池
  在一些小的程式裡,沒什麼必要添加記憶體管理模組在裡面。但是對於比較複雜的代碼,如果需要很多的記憶體操作,那麼加入自己的記憶體管理是有必要的。至少有一些好處:能夠加快記憶體的申請和釋放;能夠輕鬆的尋找記憶體泄露問題;能夠對整個軟體的記憶體消耗做一個比較精確的統計;對以後的最佳化有很大的好處等等。所以,在我的解譯器裡,我加入了一個簡單的記憶體管理模組,仿造了記憶體池的做法。
  主要思想是這樣的:
  a.記錄所有的申請的記憶體
  b.當釋放記憶體時,記錄下來以供下次申請使用
  c.申請記憶體時,可以直接使用前面釋放過的記憶體
  為了達到以上的功能。我為申請記憶體的大小劃分粒度,例如:我得粒度這麼安排{16,32,64,128,...}那麼申請17個位元組的大小時候,我會申請32個位元組的大小。這樣子方便管理。並且為每個粒度建立一個可用記憶體的雙向鏈表。申請記憶體時,就可直接從這些鏈表頭中申請(即將一個節點從鏈表頭移除,作為被申請的空間,並插入到在使用的鏈表中),記憶體的釋放則是一個想法的過程。這些的儲存結構如下所示:
 
  (圖1.1 記憶體池的儲存結構)
 
typedef struct _pool_block{
    int size;
    void * data;
    struct _pool_block * next;
    struct _pool_block * pre;
}pool_block_t;

typedef struct _pool{
    int num_all;
    int num_free;
    pool_block_t * list_all;
    pool_block_t * list_free[POOL_ATOM_NUM];
}pool_t;

int pool_atom_tab[POOL_ATOM_NUM] = {
    32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, -1
};

  說明:
  a.記憶體的申請會按照pool_atom_tab數組中的大小對齊,比如申請10byte,那麼,我會申請32byte.
  b.為每個粒度儲存一個雙向鏈表,用於儲存被釋放的記憶體。如果要申請的記憶體超過8192,那麼我直接調用系統的malloc,釋放時,直接調用free.
  c.記憶體申請過程:到相應的粒度鏈表(list_free)中查看是否有可用記憶體,如果有,直接將它從該list_free鏈表中移動到list_all鏈表。
  d.記憶體釋放過程:要釋放的記憶體必定儲存在list_all中,根據它的大小,把它移動到相應的list_free鏈表。
  e.pool_block_t結構被放置在申請記憶體的前面,則在釋放時,直接根據Buffer指標就可得到pool_block_t的位置,從而得到next和pre,快速的在鏈表中移動。

2.棧
  棧在解譯器中用到的地方很多,不管是運算式的解析,還是代碼塊的解析,類型的解析,等等都用到了棧。所以不實現它是不可能的事,不過在資料結構中他是最簡單的了,無非就是申請一個空間,按一個一個的節點儲存進去,按一個一個的節點取出來。沒什麼技巧在裡面,只是這個我讓棧的大小空間是自動成長和減小的,這麼做的目的是:棧的空間僅僅限制於記憶體的大小。但是,這麼做得缺點是,當棧的空間大小自動變化時,棧內的資料要被複製一遍,這務必會影響效率。但沒有辦法,暫時之能這樣了。唯一的辦法是在時間和空間上做一個選擇。
  棧的儲存結構如下:
 
  (圖1.2 棧的儲存結構)
 
typedef struct _stack{
    int item_len;
    int item_num;
    int stack_size;
    char *p;
}stack_t;
  
  說明:
  item_len:   儲存每個節點的長度
  item_num:   棧中節點的個數
  stack_size: 棧中可儲存的節點個數
  p:          指向棧空間
  a.當節點的個數item_num大於stack_size,那麼必須重新申請空間,將原來的資料拷貝到新的空間。
  b.當節點的個數減小到一定的數量時,可以重新申請小的資料空間,釋放原來大的空間。

3.hash表
  hash由於其快速的尋找能力而著稱,但是它太浪費記憶體了,所以用得的比較少,僅僅是在函數的調用時被使用。因為函數的調用是頻繁的,如果從頭尋找函數,那將浪費很多的時間。這裡引入hash也是必要的。
 
#define HH_TAB_SIZE 128

typedef struct _hh_node{
    unsigned int hash, klen, dlen;
    void * key;
    void * data;
    struct _hh_node *next;
}hh_node_t;

typedef struct _hh_head{
    unsigned int node_num;
    hh_node_t *  node_list;
}hh_head_t;

typedef struct _hh_hash{
    hh_opts_t opts;
    hh_head_t tabs[HH_TAB_SIZE];
}hh_hash_t;

typedef struct _hh_opts{
    int (*cmp_key)(void *key1, void *key2);
    unsigned int (*get_hash)(void *key);
    void * (*new_key)(int);
    void * (*new_data)(int);
    void (*del_key)(void *key);
    void (*del_data)(void *data);
}hh_opts_t;

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.