0

開発スキルのさびをかき集めるためにリンク リストを実装してきましたが、中間要素を削除するテスト中に valgrind がサイズ 4 の無効な読み取りを報告することに気付きました。

==1197== Invalid read of size 4
==1197==    at 0x804885C: main (list.c:135)
==1197==  Address 0x426e76c is 4 bytes inside a block of size 12 free'd
==1197==    at 0x40257ED: free (vg_replace_malloc.c:366)
==1197==    by 0x804875E: list_remove (list.c:112)
==1197==    by 0x8048857: main (list.c:137)

これをトリガーするメインのコードは次のとおりです。

    for (iter = l2->head; iter; iter = iter->next) {
            if (iter->n >= 10 && iter->n <= 14)
                    list_remove(l2, iter);

削除機能は次のとおりです。

void list_remove(struct list *list, struct node *node)
{
        if (node == list->head && node == list->tail) {
                list->head = list->tail = NULL;
        }
        else if (node == list->head) {
                list->head = node->next;
                list->head->prev = NULL;
        }
        else if (node == list->tail) {
                list->tail = node->prev;
                list->tail = NULL;
        }
        else  {
                struct node *prev, *next;
                prev = node->prev;
                next = node->next;
                prev->next = next;
                next->prev = prev;
        }

        free(node);
}

私が間違っている可能性があることについて何か考えはありますか?

4

3 に答える 3

4

ループで値を解放し、逆参照して「次の」ポインターを取得します。これを正しく行うには、一時値が必要です。

    for (iter = l2->head; iter; iter = next) {
            next = iter->next;
            if (iter->n >= 10 && iter->n <= 14)
                    list_remove(l2, iter);
    }
于 2012-08-04T21:46:07.523 に答える
1

iterのときにポインタを離していますfree(node)iter->next次に、もう存在しないものから読み取ろうとします。

于 2012-08-04T21:48:41.053 に答える