0

它只返回一个地址,没有任何调试器错误,尽管我的 DEV C++ 和 Code::Blocks 编译器都显示发送不发送 Windows 错误,但它们只初始化类对象,我已经包含了代码,谁能告诉我为什么会发生

#include <iostream>
#include <conio.h>
using namespace std;
struct Node
{
    int data;
    Node *nextptr;
};


class CLLIST{

private:

     Node*firstptr;
     Node*lastptr;

public:
     CLLIST(){

     cout << "Constructor Called !";
      firstptr=lastptr=NULL;
}

void insert_at_back(int val){

         if(firstptr==NULL) //it means start of C.LIST
         {
             Node*temptr = new Node; //means firstptr = temptr
             firstptr->data=val;
             firstptr=temptr;
             firstptr->nextptr=firstptr;
         } else{

             Node*temp1 = new Node;
             Node*temp2 = new Node;

             temp1 = firstptr;
             while(temp1->nextptr!=firstptr) //traversing
             {
                 temp2 = temp1->nextptr;
                 temp2->data = val; //inserted at back
                 temp2->nextptr=firstptr; //circle completed
             }
         }
}

void printit(){

           // functiont o print all the circular link lists data
           Node*temp3ptr= new Node;
           temp3ptr = firstptr;

           while(temp3ptr->nextptr!=firstptr)//traversing
           {
              cout << temp3ptr->data;
              cout << endl;
           }
}
};


  int main()
  {
    CLLIST obj1;

    obj1.insert_at_back(10);
    obj1.insert_at_back(20);
    obj1.insert_at_back(30);

    obj1.printit();

    cout << "Done !";

    getch();
  }
4

1 回答 1

3

您当前代码的一些问题(可能还有更多,但您应该首先专注于解决这些问题)


问题 1

         if(firstptr==NULL) //it means start of C.LIST
         {
             Node*temptr = new Node; //means firstptr = temptr
             firstptr->data=val;
             firstptr=temptr;
             firstptr->nextptr=firstptr;
         } else{

^ 与firstptr->data=val;您一起取消引用firstptr,即使它仍然是NULL. 交换它和下一行,这样它就变成了:

         if(firstptr==NULL) //it means start of C.LIST
         {
             Node*temptr = new Node; //means firstptr = temptr
             firstptr=temptr;
             firstptr->data=val;
             firstptr->nextptr=firstptr;
         } else{

或者更好firstptr = new Node;的做法是:直接跳过temptr


问题 2

     Node*temp1 = new Node;
     Node*temp2 = new Node;

     temp1 = firstptr;
     while(temp1->nextptr!=firstptr) //traversing
     {
         temp2 = temp1->nextptr;
         temp2->data = val; //inserted at back
         temp2->nextptr=firstptr; //circle completed
     }

^ 这是内存泄漏;new在堆上为它们分配内存,当您将临时节点分配给指向firstptr. 只需声明temp1temp2而是:

     Node*temp1;
     Node*temp2;

问题 3

    while(temp1->nextptr!=firstptr)

^ 这个while循环永远不会运行,因为:

  • 你从firstptrnull开始
  • 然后添加一个节点,并firstptr->next指向firstptr.
  • 然后,当您尝试添加第二个节点时,它会执行分配的工作temp1 = firstptr;,但不会运行 while 循环,因为firstptr->next == firstptr

问题 4

正如@aleguna 指出的那样:

       Node*temp3ptr= new Node;
       temp3ptr = firstptr;

^ 这是另一个内存泄漏,原因与问题 2 中所述相同。只需声明temp3ptr

       Node*temp3ptr;

问题 5

       while(temp3ptr->nextptr!=firstptr)//traversing
       {
          cout << temp3ptr->data;
          cout << endl;
       }

^ 在这里,您需要一种实际迭代循环链表的方法,现在它只是重复打印第一个节点(好吧,从技术上讲,您的代码的其他部分还不允许您将第二个节点添加到链表中,要么)

就像是:

       while(temp3ptr->nextptr!=firstptr)//traversing
       {
          cout << temp3ptr->data;
          cout << endl;
          // Can technically do it without the if-check since this
          // is circular, but better to code defensively.
          if (temp3ptr->next != NULL) {
              temp3ptr = temp3ptr->next;
          }
       }
于 2012-12-13T16:30:36.393 回答