2

現在、次のような構造体のリストを使用しています。

リストから要素を削除する関数です。リスト全体を処理する for ループから始めます。i がエントリ数より小さい場合は、if ステートメントに入ります。それからホールド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

ループに大きな間違いがあります。

「上に移動」される要素は 1 つだけで、null に設定された後に上に移動されます。

したがって、このリスト -> wlist_ptr[i] = NULL; list->wlist_ptr[i-1] = list->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 に答える