2017-12-20 12 views
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)으로 설정합니다.

FD_Remove으로 전달하는 FileDesc이 목록의 마지막 항목이라고 가정합니다.

FD_Remove(FDescList, 0x00000005);

그래서 우리는 0x00000005 법인을 가지고있는 메모리는 이제 해방이되어 있다고 가정 할 수 있습니다.

지금 나는 단지이 값은 링크 된 목록에서 이전에 해제 된 개체에 나타나는 것으로 가정 할 FD_Add(FDescList, FileDesc, 'whatever');

호출합니다.

문제

문제 엔티티 대신 해제 메모리 NULL로 설정되어 있으며,이 함수는 FileDesc 및 추가 그것의 NULL 메모리 블록 대신 내부 후의 엔티티 '무엇'데이터.

질문 나는이 원인이되는 내 FD_Remove 기능을 잘못하고 있는가, 그리고 어떻게이 문제를 해결하기 위해 제 기능을 향상시킬 수 있습니다 무엇

?

답변

2

링크 된 목록에서 요소를 제거하려면 제거 할 요소에 주변 요소 포인터를 업데이트 한 다음 요소를 해제해야합니다. 아무 것도 할당하거나 복사 할 필요가 없습니다. 요소가 제거되는 경우 연결리스트의 head입니다 조심,

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); 

을하지만 :

대신 사용해보십시오. 그렇다면, 위의 함수가 직접 할 수없는 포인터도 업데이트해야합니다. 대신 다음과 같이해야합니다.

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);