Singly Linked-List(如何正确删除/释放实体?)

问题描述 投票:1回答:1

背景

我有以下代码

VOID FD_Remove(FDescs List, PVOID FileDesc) {
    while (List) {
        if (List->Sock == FileDesc) {
            List->Next = (FDescs) LocalAlloc(sizeof(Network::FDesc));
            if (List->Next != ERROR) {
                FDescs Element = List->Next;

                List->Sock = List->Next->Sock;
                List->Host = List->Next->Host;
                List->Path = List->Next->Path;

                List->Next = Element->Next;
                LocalFree(Element);
            }
        } List = List->Next;
    }
}

笔记

基本上,当我在链表中​​创建一个新条目时。我将分配给定结构大小的新内存块并将其设置为列表的末尾,以与此_Remove函数中相同的方式查找块。

但是,当我试图删除一个实体。如上所示,我从列表中释放实体,并将当前实体设置为列表中的下一个条目。问题是,似乎LocalFree调用实际上没有将分配的内存设置回未分配的内存块。当我查看链表时,当前实体只是将其所有条目设置为NULL (0)

假设我传递给FileDescFD_Remove是列表的最后一个条目。

FD_Remove(FDescList, 0x00000005);

所以我们可以假设现在释放了具有0x00000005实体的内存。

现在我打电话给FD_Add(FDescList, FileDesc, 'whatever');

我只假设这些值将出现在Linked-list中先前释放的实体中。

问题

问题是实体被设置为NULL而不是释放的内存,并且该函数在FileDesc内存块之后而不是在其内部将NULL和'whatever'数据添加到实体。

在我的FD_Remove函数中我做错了什么导致了这个问题,如何改进我的功能来解决这个问题呢?

c winapi singly-linked-list
1个回答
2
投票

从链表中删除元素只需要更新要删除的元素的周围元素指针,然后释放该元素。您无需分配或复制任何内容。

试试这个:

VOID FD_Remove(FDescs List, PVOID FileDesc) {
    FDescs Previous = NULL;
    while (List) {
        if (List->FDesc == FileDesc) {
            if (Previous)
                Previous->Next = List->Next;
            LocalFree(List);
            return;
        }
        Previous = List;
        List = List->Next;
    }
}

FD_Remove(FDescList, (PVOID)0x00000005);

但是,请注意被删除的元素是否是链接列表的head。如果是这样,你需要更新那个指针,上面的函数不能直接做。你不得不做更像这样的事情:

VOID FD_Remove(FDescs *List, PVOID FileDesc) {
    if (!List) return;
    FDescs Element = *List, Previous = NULL;
    while (Element) {
        if (Element->FDesc == FileDesc) {
            if (*List == Element)
                *List = Element->Next;
            if (Previous)
                Previous->Next = Element->Next;
            LocalFree(Element);
            return;
        }
        Previous = Element;
        Element = Element->Next;
    }
}

FD_Remove(&FDescList, (PVOID)0x00000005);
© www.soinside.com 2019 - 2024. All rights reserved.