2014-03-01 5 views
0

실제로 노드를 삭제하지 않고 메모리를 확보하는 것처럼 느껴집니다. 나는 포인터를 움직이는 것만으로 링크 된 목록을 인쇄 할 때 목록에서 삭제 한 요소가 인쇄되지 않는다고 생각합니다. 그래서 내 질문은 내가 실제로 노드를 삭제하거나 노드를 삭제하는 것처럼 보이도록 포인터를 다시 정렬하는 것입니다 (본질적으로 링크를 끊지 만 노드를 삭제하지 않음)? 어떤 도움을 주셔서 감사합니다.C++에서 연결된 목록의 노드를 올바르게 삭제하는 방법

void SLL::deleteNode(int target){ 
Node *current = new Node; 
Node *previous = new Node; 

for (current = front->next, previous = front; current != NULL; current = current->next, previous=previous->next){ 
    if (previous->data == target && previous == front){ 
     front = previous->next; 
     delete[] previous; 
     return; 
    //This if statement deletes the element if its the front 
    } 

    else { 

     if (previous->data == target && previous->next == NULL){ 
      previous = NULL; 
      delete[] current; 
      return; 
     //This if statement deletes the node if it is the back 
     } 


     else if (current->data==target) 
     { 
      previous->next = current->next; 
      delete[] current; 
      return; 
     //This if statement deletes a node if it is in the middle 
     } 
    } 
    } 

    delete[] current; 
    delete[] previous; 
} 
+0

왜 'current'와 'previous'를 하나의 인스턴스로 선언 할 때 배열 delete ('delete []') 버전을 사용하고 있습니까? – mathematician1975

+0

'front-> next'로 열거 알고리즘을 시작하는 것은 관련이 있습니다. * 실제로 데이터가 포함되지 않은 사전 할당 된 "헤드"노드를 사용하지 않는다고 알려주십시오. 필요하지 않습니다. 그리고 노드를'new Node [n]'으로 할당하지 않으면 잘못된'delete' 연산자를 사용하게됩니다. – WhozCraig

+0

나는 모른다. 나는 이것을 시도했다. 질문에 대답하십시오. – WombatCombat

답변

5
Node *current = new Node; 
Node *previous = new Node; 

이 코드는 메모리 누수가 발생합니다 - 당신은 결코이 메모리를 삭제하지 않습니다. 당신은 메모리 할당없이 포인터를 선언 할 수 있습니다 : 당신이 실제로 노드를 삭제할 수 있도록

Node *current = nullptr; 
Node *previous = nullptr; 

delete 포인터의 메모리를 삭제합니다. Node*delete[]을 사용하면이 잘못되었으므로 new[]으로 할당 된 메모리에만 사용해야합니다. 부적절하게 사용하면 정의되지 않은 동작이 발생합니다. 노드를 올바르게 삭제하려면 연산자을 삭제하십시오.

메모리 누수 탐지 도구를 사용하면 프로그램에서 메모리 누수가 있는지 확인할 수 있습니다.

목록 요소를 삭제하는 코드 :

Node* pCur = pHead; 
Node* pPrev = pCur; 

while (pCur && pCur->data != target) { 
    pPrev = pCur; 
    pCur = pCur->next; 
} 

if (pCur==nullptr) // not found 
    return NOT_FOUND; 

if (pCur == pHead) { // first element matches 
    pHead = pCur->next; 
} else { 
    pPrev->next = pCur->next; 
} 

// pCur now is excluded from the list 

delete pCur;  // deallocate its memory 

: 우리는 목록 의 머리를 가리키는 pHead을 말한다 (하지만 당신이 그런 것들을 자신을 작성하는 경우 훨씬 더 줄 것이다) 포인터 (커뮤니티 추가)에 포인터를 사용

대체

당신이 목록에 을 실제 포인터를 사용하면 위의 새로운 빛에 걸릴 수 있습니다 열거를 수행하십시오. 다음은 pp이 헤드 포인터의 주소 (포인터가 가리키는 노드가 아니라 실제 포인터 자체) 인 으로 시작됩니다. 우리는 pp까지 대상을 삭제할 노드가있는 노드를 가리키는 포인터의 주소를 유지할 때까지 포인터를 이동합니다 (어떤 노드에서는 next 포인터가 될 수 있으며, 아무런 차이가 없습니다). 주소 지정되는 포인터가 자체 노드의 next 값으로 설정되면 대상 노드가 제거됩니다.

이 실제로 어떻게 작동하는지 확인하기 위해 디버거에서 감시해야하지만, 알고리즘은 정말 무슨 일이 일어나고 있는지 주어진 현저하게 간단하다

Node **pp = &pHead; 
while (*pp && (*pp)->data != target) 
    pp = &(*pp)->next; 

if (*pp) 
{ 
    Node *victim = *pp; 
    *pp = victim->next; 
    delete victim; 
} 

그것의 모든 그게 전부입니다. 그리고 무료로 특별한 경우없이 머리 노드를 제거 할 수 있습니다. 희망이 도움이됩니다.

+0

고맙습니다. 나는 더 이상이 시점부터 새로운 것을 사용하지 않을 것입니다. 내 질문은 여전히 ​​남아 있지만, 어떻게 내 대상 노드를 삭제합니까? 나는 당신이 그것에 만지는 것을 압니다. 그러나 아마도 당신은 조금 더 설명 할 수 있습니다. – WombatCombat

+0

@ user3291106 - 샘플 코드를 제공합니다. 그러나 직접 작성하는 것이 훨씬 더 유용 할 것입니다. 이제 이중 연결 목록을 시도하고 끝에서 검색하십시오. –

+0

@Alex 'pHead'가 삭제 될 노드를 가리킬 때 어떻게 끝나나요? 따라 : while 루프는 건너 뛰고 아무 것도하지 않습니다. 'pPrev','pCur','pHead'가 모두 같은 노드를 가리키고 있기 때문에''pHead-> next''가 효과적으로 할당 될 것입니다. 그런 다음 헤드 노드는'delete pCur; '로 파괴되어 목록의 나머지 부분이 모두 고아이고 유효하지 않은 불확실한 주소를 가진 세 포인터를 남겨 둡니다. 한마디로, * ouch *. – WhozCraig

관련 문제