2012-02-21 24 views
1

我試圖使用OpenBSD的sys/queue.h文件來操作鏈表。sys/queue.h:使用LIST_REMOVE

我正在爲一個小型微控制器寫一個緩存引擎。頁面在使用時會存儲在緩存中,並且在需要內存時用於像malloc這樣的其他內容。

該任務需要找到最小命中數緩存頁面(命中數最少的頁面最不可能被使用)並將其釋放。但是,我遇到了一個相當簡單的錯誤。

這是到目前爲止我的功能:

void _fmem_cache_malloc_purge(int requested_size) 
{ 
    int n = ((requested_size/FMEM_SECTOR_SIZE) + 1) * FMEM_SECTOR_SIZE; 
    struct s_fmem_cache_entry *entry, *lowentry; 
    long int lowhits; 
    fmem_acquire(); 
    for(; n > 0; n--) 
    { 
     // Traverse the cache table. Find an entry with a minimum number of hits. 
     lowhits = -1; 
     LIST_FOREACH(entry, &fmem_cache, entry_ptr) 
     { 
      if(lowhits == -1 || lowhits > entry->hits) 
      { 
       lowentry = entry; 
       lowhits = entry->hits; 
      } 
     } 
     // Free the minimum entry. 
     assert(lowhits > 0); 
     LIST_REMOVE(lowentry, entry_ptr); <-- error occurs here (line 170) 
     mmgr_free(lowentry->data); 
     mmgr_free(lowentry); 
     fmem_cache_size--; 
    } 
    fmem_release(); 
} 

定義(接近相同文件的頂部):

struct s_fmem_cache_entry { 
     fAddr addr; 
     char data[FMEM_SECTOR_SIZE]; 
     long int hits, ctime; 
     LIST_ENTRY(fmem_cache_entry) entry_ptr; 
    }; 

LIST_HEAD(s_fmem_cache_head, s_fmem_cache_entry) fmem_cache; 

我得到的錯誤是:

flashmem.c: In function '_fmem_cache_malloc_purge': 
flashmem.c:160: warning: assignment from incompatible pointer type 
flashmem.c:170: error: dereferencing pointer to incomplete type 

我覺得這是一個簡單的錯誤,但C對我來說是新的。

+0

哪些線是160/170? – Eregrith 2012-02-21 08:05:02

+0

當您看到「不完整類型」警告時,您知道您錯過了#include文件。如果你想知道哪一個....你必須顯示行號。 – 2012-02-21 08:23:10

+0

@ J-16 @Eregrith'< - 此處出現錯誤標記行170.'LIST_FOREACH(entry,&fmem_cache,entry_ptr)'爲行160. – 2012-02-21 11:44:52

回答

0

你應該檢查你使用的類型LIST_FOREACH(我猜這是160行)和LIST_REMOVE(10行後,所以它必須是170)。
fmem_cacheentry_ptr的定義不在您的文章中,所以我不能說錯誤是什麼。

我建議你仔細閱讀你使用的列表宏的文檔,並檢查你使用的所有類型是否正確。

它也好像struct s_fmem_cache_entry未在您的代碼中定義(或未定義它的頭部)。

2

的問題是在struct s_fmem_cache_entry定義在LIST_ENTRY(fmem_cache_entry) entry_ptr

從queue.h我們可以看到,

#define LIST_ENTRY(type)            \ 
struct {                \ 
     struct type *le_next; /* next element */      \ 
     struct type **le_prev; /* address of previous next element */ \ 
} 

所以當你使用LIST_ENTRY它基本上變成了無名的結構如下圖所示。這就是編譯器給出錯誤的原因。

struct { 
    struct fmem_cache_entry *le_next; 
    struct fmem_cache_entry **le_prev; 
} entry_ptr; 

您可以輕鬆地通過不使用LIST_ENTRY並通過聲明struct entry_ptr自己避免這種情況。我不確定任何替代解決方案。

2
LIST_ENTRY(fmem_cache_entry) entry_ptr; 

應該

LIST_ENTRY(s_fmem_cache_entry) entry_ptr;