【问题标题】:How do I use the list_for_each macro in list.h (from the Linux kernel) properly?如何正确使用 list.h(来自 Linux 内核)中的 list_for_each 宏?
【发布时间】:2013-04-02 00:37:22
【问题描述】:

我很难使用 Linux 内核中的 list.h 为我的代码提供链表功能。我怀疑我几乎有功能代码,但我在某处混淆了指针。

如何正确使用 list_for_each 宏?在我的代码中,它陷入了无限循环并且没有退出列表。下面是我的代码中的 sn-p 问题所在(查看 add_kv 函数):

dict_entry *alloc_dict(void)
{
    //allocates the linked list head node
    dict_entry *d = malloc(sizeof(dict_entry));
    INIT_LIST_HEAD(&d->list);
    return d;
}
 
void free_dict(dict_entry *d)
{
    //TODO: free each dict_entry struct and their keys and values.
    free(d);
}

int add_kv(dict_entry *d, char *key, char *value)
{
    if(!key || !d) return 0; //if key or d is null, return 0

    struct list_head *p; //serves as the cursor
    dict_entry *entry; //empty dict_entry
    entry = alloc_dict(); //allocate memory for it

    list_for_each(p, &d->list){
        d = list_entry(p, dict_entry, list); //CHANGED TO d FROM entry
        printf("gothere, p = %p\n",p); // something in here is creating an infinite loop. p is moving back and forth. this is the big problem in this code
        if(strcmp(entry->key, key) == 0){
            free(entry->value);
            entry->value = 0;
            entry->value = malloc(strlen(value));
            strcpy(entry->value, value);
            return 1; //how do i get rid of entry?
        }
    }
    //If you haven't returned by now, continue on to add a new entry at the end of the list 
    entry->key = malloc(strlen(key)); //allocate memory for the key
    strcpy(entry->key, key); //copy the key value to the key in the entry
    entry->value = malloc(strlen(value)); //allocate memory for value
    strcpy(entry->value, value); //copy value value to the value in the entry
 
    list_add(&entry->list,&d->list); //tacks the list of the new entry onto the existing list (provided as d)
    return 1;
}

下面是 list.h 中的 list_for_each 宏,供参考:

/**
 * list_for_each    -   iterate over a list
 * @pos:    the &struct list_head to use as a loop cursor.
 * @head:   the head for your list.
 */
#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

这里是 list.h 中的 list_entry 宏,也供参考:

/**
 * list_entry - get the struct for this entry
 * @ptr:    the &struct list_head pointer.
 * @type:   the type of the struct this is embedded in.
 * @member: the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

...以及我正在使用的 dict_entry 结构:

  6 typedef struct {
  7   char *key;
  8   char *value;
  9   struct list_head list;
 10 }dict_entry;

...运行时,会发生这种情况:

gothere, p = 0x1178050
gothere, p = 0x1178020
gothere, p = 0x1178050
gothere, p = 0x1178020

一遍又一遍。

关于如何使用 list.h 实现列表的一个很好的解释可以找到 here 以供参考。

【问题讨论】:

  • dict_entry 是如何定义的?

标签: c linked-list


【解决方案1】:

由于某种原因,您正在重新分配变量 d,这会破坏 list_for_each 宏。

你有这个代码:

list_for_each(p, &d->list){
    d = list_entry(p, dict_entry, list);

宏在每次迭代时重新评估&d->list,以查看何时到达列表末尾。由于d 被重新分配,因此此检查失败并永远循环。

【讨论】:

  • 之前,该代码更加理智——它曾经是:list_for_each(p, &d->list){ entry = list_entry(p, dict_entry, list) 但我惊慌失措地更改了它以重新分配 d,因为这只是一遍又一遍地打印出一个地址——无限循环仍然发生。因此,我将代码编辑为 not reallocate d,但循环宏仍然存在问题。
  • 我猜你应该使用list_for_each_entry()
猜你喜欢
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 2019-02-11
相关资源
最近更新 更多