لماذا "حذف العقدة" تحطم تطبيق قائمة C ++ مرتبط؟

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

  •  06-09-2019
  •  | 
  •  

سؤال

من المفترض أن تقوم طريقة jdeletEafter في فئة قائمة قوتي المرتبطة بحذف العقدة مباشرة بعد مرت العقدة كوسيطة. إذا كان الأمر كذلك، فأنا لا أعرف، لكنه يغلق فجأة تطبيق وحدة التحكم الخاصة بي عند "حذف TLP؛" (مؤشر قائمة TEMP) يحصل على القراءة. مدرسي، مستخدمي منتدى البرمجة ولم أكن بعد تحديد جذر هذه المشكلة.

مكتوب في 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 لاجتياز القائمة وتوفير العقدة المناسبة كوسيطة JDELETEFTER.

لا يوجد حل صحيح

نصائح أخرى

تلميح بسيط: قم بإزالة جميع الاختبارات الخاصة بتفشل التخصيص - لن يحدث أبدا على نظام Windows AMD تعقد الرمز. وإذا حدث ذلك، فأنت لا تتعافى منها، وبالتالي فإن الاختبارات عديمة الفائدة مضاعفة.

اتضح أنه كان هناك تعارض مع بيان حذف الخاص بي في My Virtual Destructor. كل شيء يعمل الآن. شكرا لإلقاء نظرة على التعليمات البرمجية الخاصة بي.

أما بالنسبة ل Notrathows - أفعل ذلك بهذه الطريقة لأن نصنا قدم الفكرة وأنا لا أعرف كيفية التعامل مع الاستثناءات بعد. شكرا على النصيحة، ولكن.

نصائح استعراض الكود:

JawaLinkT* tlp;                         //new list node

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

هو أكثر قابلية للقراءة على النحو التالي:

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

(أيضا، انظر تعليق نيل أعلاه لماذا استخدام Nothrow دون فعل أي شيء حيال ذلك)

يتم تناثر الرمز أيضا مع تسرب الذاكرة المحتملة العشوائية:

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

فيما يتعلق بالسؤال، هذا كثير من التعليمات البرمجية للقراءة دون الكثير مثل تتبع المكدس للبحث عن علة عامة فقط، لكنني أعتقد أنه قد يتم تنفيذ jdeletEfter بشكل غير صحيح. النظر في الحالة عندما يتم تمرير الوظيفة العقدة قبل الذيل. سأقطعها هناك لأنه يبدو وكأنه الواجبات المنزلية؛ ولكن إذا كنت لا تزال تواجه مشكلة وتعليق وسأوضح.

تحرير: وأدركت أنني كنت مخطئا. لا يهم!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top