sys / queue.h:使用LIST_REMOVE

时间:2012-02-21 08:03:13

标签: c list pointers

我正在尝试使用OpenBSD中的sys/queue.h文件来操作链接列表。

我正在为一个小型微控制器编写缓存引擎。页面在使用时存储在缓存中,并在其他内容(例如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对我来说是新的。

3 个答案:

答案 0 :(得分: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来轻松避免这种情况。我不确定是否有任何替代解决方案。

答案 1 :(得分:2)

LIST_ENTRY(fmem_cache_entry) entry_ptr;

应该是

LIST_ENTRY(s_fmem_cache_entry) entry_ptr;

答案 2 :(得分:0)

你应该检查你使用的LIST_FOREACH类型(我猜这是第160行)和LIST_REMOVE(10行以后,所以它必须是170)。
fmem_cacheentry_ptr的定义不在您的帖子中,因此我无法说出错误是什么。

我建议您仔细阅读您使用的列表宏的文档,并检查您使用它们的所有类型是否正确。

似乎struct s_fmem_cache_entry未在您的代码中定义(或未包含其定义的标头)。