如何使用列表中的list_for_each宏。h(来自Linux内核)正确吗?

时间:2021-09-23 20:59:30

I am having a hard time using list.h from the Linux kernel to provide linked list functionality for my code. I suspect that I almost have functional code, but I am mixing up pointers somewhere.

我在使用列表时遇到了困难。h来自Linux内核,为我的代码提供链表功能。我怀疑我几乎有函数代码,但我在某个地方混淆了指针。

How do I use the list_for_each macro properly? In my code, it gets stuck in an infinite loop and does not exit the list. Below is the snippet from my code in which the problem lies (look in the add_kv function):

如何正确使用list_for_each宏?在我的代码中,它陷入了一个无限循环,并没有退出列表。下面是问题所在的代码片段(参见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;
}

Below is the list_for_each macro from list.h, for reference:

下面是列表中的list_for_each宏。h,供参考:

/**
 * 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)

And here is the list_entry macro from list.h, also for reference:

这是list的list_entry宏。h,也供参考:

/**
 * 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)

...and the dict_entry struct I'm using:

…我使用的dict_entry结构体:

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

...and when run, this happens:

…当运行时,会发生:

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

over and over again.

一遍又一遍。

A good explanation on how to implement lists with list.h can be found here for reference.

很好的解释了如何使用列表来实现列表。h可以在这里找到以供参考。

1 个解决方案

#1


4  

You are reassigning the variable d for some reason, and this breaks the list_for_each macro.

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

You have this code:

你有这段代码:

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

The macro reevaluates &d->list on each iteration to see when the list end is reached. Since d is reassigned, this check fails and it loops forever.

宏在每次迭代中重新评估&d->列表,以查看何时到达列表结束。由于d被重新分配,这个检查失败了,它将永远循环。

#1


4  

You are reassigning the variable d for some reason, and this breaks the list_for_each macro.

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

You have this code:

你有这段代码:

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

The macro reevaluates &d->list on each iteration to see when the list end is reached. Since d is reassigned, this check fails and it loops forever.

宏在每次迭代中重新评估&d->列表,以查看何时到达列表结束。由于d被重新分配,这个检查失败了,它将永远循环。