왜 "노드 삭제"? 내 C ++ 링크 된 목록 응용 프로그램을 충돌시겠습니까?

StackOverflow https://stackoverflow.com/questions/930693

  •  06-09-2019
  •  | 
  •  

문제

이후 링크 된 목록 클래스의 JDELETER 메소드는 인수로 전달 된 노드 바로 다음에 노드를 삭제해야합니다. 그렇게한다면, 나는 알지 못하지만 "tlp 삭제"에 갑자기 콘솔 애플리케이션을 닫고 있습니다. (임시 목록 포인터)를 읽습니다. 내 강사, 프로그래밍 포럼의 사용자와 나는 아직이 문제의 근본을 결정하지 않았습니다.

Dev-C ++ 4.9.9.2로 작성되었습니다.

[source]
#include "JawaListT.h"
#include <cstdlib>
#include <iostream>
#include <new.h>

/*DEFAULT CONSTRUCTOR*/
JawaListT::JawaListT()
{
    if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
    {
        this->jHead->jSetNext(this->jTail);
        this->jTail->jSetNext(this->jTail);
    }//end if allocated
}

/*INSERT NODE AFTER*/
void JawaListT::jInsertAfter(JawaLinkT* lp, int val)
{
    if(lp != NULL && lp != this->jTail)     //if passed not tail and not null
    {
        JawaLinkT* tlp;             //new list node

        if((tlp = new (nothrow) JawaLinkT) != NULL) //if dynamically allocated  
        {
            tlp->jSetNext(lp->jGetNext());  //temp.next = passed.next                   
            lp->jSetNext(tlp);      //passed.next = temp
            tlp->jSetValue(val);        //temp.data = val
        }//end if allocated
    }//end if not tail
}

/*INSERT NODE BEFORE*/
void JawaListT::jInsertBefore(JawaLinkT* lp, int val)
{
    if(lp != NULL && lp != this->jHead)     //if passed not head and not null
    {
        JawaLinkT* tlp;             //new list node

        if((tlp = new (nothrow) JawaLinkT) != NULL) //if dynamically allocated
        {
            tlp->jSetNext(lp->jGetNext());
            tlp->jSetValue(lp->jGetValue());
//          *tlp = *lp;         //copies passed node to temp node
            lp->jSetNext(tlp);      //passed.next = temp
            lp->jSetValue(val);     //passed.data = val
            if(lp == this->jTail)       //if passed is tail
            {
                this->jTail = tlp;  //tail is temp
                this->jTail->jSetNext(this->jTail); //tail.next = tail
            }//end if lp
        }//end if tlp
    }//end if head
}

/*REMOVE NODE AFTER*/
void JawaListT::jDeleteAfter(JawaLinkT* lp)
{
    if(lp != NULL && lp->jGetNext() != this->jTail) //if not tail and not null
    {
        JawaLinkT* tlp;             //temp pointer to node

        tlp = lp->jGetNext();           //temp = passed.next
        lp->jSetNext(tlp->jGetNext());      //passed.next = temp.next
        delete tlp;             //delete to what temp points
    }//end if next  

        /*code that did not work any better*/
//      tlp->jSetNext((lp->jGetNext())->jGetNext());    
//      delete lp->jGetNext();
//      lp->jSetNext(tlp);

/*Also tried declaring and/or deleting tlp outside of decision structure, and
jDeleteCurrent(tlp) since that function works properly.*/   
}

/*REMOVE CURRENT NODE*/
void JawaListT::jDeleteCurrent(JawaLinkT* lp)
{
    if(lp != NULL && lp != jHead && lp != jTail)    //if not head or tail, not null
    {   
        JawaLinkT* tlp;             //temp pointer to node

        tlp = lp->jGetNext();           //temp = passed.next
        *lp = *tlp;             //copy temp to passed
        if(tlp == jTail)            //if temp is tail
        {
            this->jSetTail(lp);     //tail = passed
            lp->jSetNext(lp);       //passed.next = passed
        delete tlp;             //delete to what temp points
        }//end if tail
    }//end if not head
}

/*LINEAR SENTINEL SEARCH*/
JawaLinkT* JawaListT::jFindItemS(int item)
{
    JawaLinkT* tlp;                 //temp pointer to node
this->jTail->jSetValue(item);               //tail.data = item

    for(tlp = jHead->jGetNext(); tlp->jGetValue() != item; tlp = tlp->jGetNext());
    /*INIT: node after head, EXIT: data found, UPDATE: increment node*/

    if(tlp == jTail)                //if sentinel found
            std::cout << item << " not in list" << std::endl;   

    return((tlp != this->jTail->jGetNext()) ? tlp : NULL);
    /*If sentinel not found, return proper node, else return null*/
}

[/source]

클래스의 Sentinel Search를 사용하여 목록을 가로 지르고 JDELETTER의 인수로 적절한 노드를 제공합니다.

올바른 솔루션이 없습니다

다른 팁

간단한 힌트 : 할당 실패에 대한 모든 테스트를 제거하십시오. Windows 플랫폼 AMD에서는 절대 발생하지 않습니다. AMD는 코드를 복잡하게합니다. 그리고 그들이 일어난다면, 당신은 그들로부터 회복되지 않으므로 테스트는 두 배로 쓸모가 없습니다.

가상 소멸자에서 내 삭제 진술과 충돌이 발생한 것으로 나타났습니다. 이제 모두 작동합니다. 내 코드를 관찰 해 주셔서 감사합니다.

Nothrows의 경우 - 우리의 텍스트가 아이디어를 소개했고 아직 예외를 처리하는 방법을 모르기 때문에 그렇게합니다. 그러나 조언에 감사드립니다.

일부 코드 검토 팁 :

JawaLinkT* tlp;                         //new list node

if((tlp = new (nothrow) JawaLinkT) != NULL)

더 읽을 수 있습니다.

if(JawaLinkT* tlp = new (nothrow) JawaLinkT)

(또한 실제로 아무것도하지 않고 Nothrow를 사용하는 이유 위의 Neil의 의견을 참조하십시오)

코드는 또한 임의의 잠재적 메모리 누출로 가득 차 있습니다.

if((this->jHead = new (nothrow) JawaLinkT) && (this->jTail = new (nothrow) JawaLinkT))
// What if first new succeeds and second fails?

질문에 관해서는, 이것은 스택 추적만큼 일반적인 버그를 찾는 것만 큼 많은 코드를 읽을 수있는 많은 코드이지만, jdeleter가 잘못 구현 될 수 있다고 생각합니다. 기능이 꼬리 앞에 노드를 통과하는 경우를 고려하십시오. 숙제처럼 보이기 때문에 거기에서 잘라낼 것입니다. 그러나 여전히 문제가 있다면 의견을 말하면 명확히하겠습니다.

편집 : 그리고 나는 내가 틀렸다는 것을 깨달았다. 신경 쓰지 마!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top