2

我目前在结构中使用一个列表,如下所示:

这是一个从列表中删除元素的函数。我从一个 for 循环开始遍历整个列表。如果 i 小于条目数,则进入 if 语句。然后它把旧位置变成一个hold ptr。将旧的 on = 设置为 NULL,然后移动列表,以便下面的元素占据其位置。

这是我调用此函数时的示例列表:

100 125 150

当我这样做并且我想从列表中删除 150 时,它会通过但无法访问列表中的内存 -> wlist_ptr[i] -> eth_address。然后我得到一个设置错误。有什么办法可以避免丢失轨道吗?

4

2 回答 2

0

一些例子:

struct wifi_info_t *wifilist_remove(struct wifilist_t * list, int user_address)
{
    int i;
    struct wifi_info_t *ptr;
    ptr = NULL;
    for(i=0; i < wifilist_number_entries(list); i++)
    {
        if(list -> wlist_ptr[i] -> eth_address == user_address)
        {
            ptr = list -> wlist_ptr[i];
            if(i != (wifilist_number_entries(list) -1))
            {
                //replace it with last element
                list -> wlist_ptr[i] = list -> wlist_ptr[wifilist_number_entries(list)-1];
                list -> wlist_ptr[wifilist_number_entries(list)-1] = ptr;
            }
            //you can use free and realloc there if you want
            list->wlist_entries--;
        }
    }
    //why? don't do that
    return ptr;
}
于 2013-08-30T04:27:07.667 回答
0

循环中有一个很大的错误。

只有一个元素被“上移”,并且在设置为 null 后上移。

所以,这个列表 -> wlist_ptr[i] = NULL; 列表->wlist_ptr[i-1] = 列表->wlist_ptr[i];

需要对此进行更改以防止将 NULL 向上移动:

        list->wlist_ptr[i-1] = list->wlist_ptr[i];
        list -> wlist_ptr[i] = NULL;

但是,需要一个循环来遍历列表的其余部分以将它们也向上移动。 memmove是你的朋友。还要记住,完成后,您不想i为下一次迭代增加,因为列表中的下一个元素现在将位于原始i位置。

也许这可以完成这项工作:

struct wifi_info_t *wifilist_remove(struct wifilist_t * list, int user_address)
{
    int i;
    int count;
    struct wifi_info_t *ptr;
    ptr = NULL;

    count = wifilist_number_entries(list);

    // TODO: take out the ( ptr == NULL ) logic if more than one match needs to be
    //       removed.
    for(i=0; ( i < count ) && ( ptr == NULL ); i++)
    {
        if(list -> wlist_ptr[i] -> eth_address == user_address)
        {
            ptr = list -> wlist_ptr[i];
            if ( i < ( count - 1 ) )
                memmove(&(wlist_ptr[i]), &(wlist_ptr[i + 1]), (count - (i + 1)) * sizeof(wlist_ptr[0]));

            // TODO: decrement the length of the list returned by
            // wifilist_number_entries(list)
        }
    }
    if(ptr != NULL)
    {
        list->wlist_entries--;
    }
    return ptr;
}

请注意,我只是在这里输入了这个,所以它可能有语法错误等。

于 2013-08-30T04:28:16.773 回答