2017-07-06 31 views
0

我试图从两个链接列表中添加数字,并将其放入第三个。它增加了很好,但我的代码块编译器停止响应,而运行此代码可能是因为无限循环或一些例外。在链接列表中添加两个数字

以下代码在链接列表中添加两个以相反顺序存储的数字。

struct Node{ 
    int x; 
    Node* next; 
}; 

class LinkedList{ 

    public: 
     Node* head; 
     LinkedList(){ 
      head = NULL; 
     } 

     void addNode(int num){ 
      Node* n = new Node(); 
      n->x = num; 
      n->next = NULL; 
      if(head == NULL){ 
       head = n; 
      }else{ 
       Node* n1 = head; 
       while(n1 != NULL){ 
        if(n1->next == NULL){ 
         n1->next = n; 
         break; 
        } 
        n1 = n1->next; 
       } 
      } 
     } 

     int popNode(){ 
      int num = NULL; 
      if (head != NULL){ 
       num = head->x; 
       head = head->next; 
      }else{ 
       cout << "Yay" << "\n"; 
       num = NULL; 
      } 

      return num; 
     } 

     void printList(){ 
      Node* n1 = head; 
      while(n1 != NULL){ 
       if(n1->next == NULL){ 
        cout << n1->x << "\n"; 
       }else{ 
        cout << n1->x << "->"; 
       } 

       n1 = n1->next; 
      } 
     } 

}; 

LinkedList* add_nums(LinkedList* l1, LinkedList* l2) { 
    LinkedList l3; 

    int num1= (*l1).popNode(); 
    int num2= (*l2).popNode(); 
    int carry = 0; 

    while(num1 != NULL || num2 != NULL){ 
     int num3 = num1+num2+carry; 

     if (num3 > 9){ 
      int temp = num3 % 10; 
      carry = (num3 - temp)/10; 
      num3 = temp; 
     } 

     l3.addNode(num3); 
     l3.printList(); 
     num1 = (*l1).popNode(); 
     num2 = (*l2).popNode(); 
    } 

    return &l3; 

} 



int main(int argc, char const *argv[]) { 
    LinkedList list1; 
    LinkedList list2; 
    list1.addNode(2); 
    list1.addNode(4); 
    list1.addNode(3); 
    list2.addNode(5); 
    list2.addNode(6); 
    list2.addNode(4); 
    (*(add_nums(&list1, &list2))).printList(); 
    return 0; 
} 

谁能告诉我我做错了什么?

更改密码输入后,我应该做的,从下面的答案:

  1. 我应该从空改变整数初始化为0。
  2. 应该使用LinkedList的对象来终止我的循环。
  3. 发生变更,我如何从一个指针

谢谢大家访问功能。

+6

这听起来像你可能需要学习如何使用调试器来遍历代码。使用一个好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏离的位置。如果你打算做任何编程,这是一个重要的工具。进一步阅读:[如何调试小程序](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – NathanOliver

+1

同意。通过这种方式,您将能够回答为什么它在运行此代码时停止响应,可能是因为无限循环或某种异常***而不是猜测。 – drescherjm

+5

'return &l3;':您返回对局部变量的引用:UB。 – Jarod42

回答

2

谁能告诉我我做错了什么?

  1. 恕我直言,你可能会做出错误的选择。 STL提供了(双向链接的)listforward list(它是单链接的)的数据结构。也许你想使用这些。您可以期望它们足够高效,无缺陷并且很重要,可以知道您是否想成为精通C++程序员。
  2. 让别人做代码审查是有意义的(有一个代码审查StackExchange网站);例如在链表中命名整数变量x可能不被认为是一种好的做法。
  3. 你没有告诉我们你的程序有什么问题。这在SO中预计。你的问题符合“脱离主题(为什么这个代码不工作?”)。你提供了这个程序,这很好。但是你没有提供你的预期输入和输出。你的计划应该做什么?如果我认为您的main函数作为测试,那么您期望的结果是什么?
  4. 看到下面的一些错误/警告

在功能popNode

int num = NULL; // should be 0, it's an integer 
... 
num = NULL; // same reason 

在功能add_nums

LinkedList l3; // it's a local variable (see return below) 
... 
while(num1 != NULL || num2 != NULL) // again num1 and num2 are integers 
.... 
return &l3; // address of a local variable :-(

我想还是你声明变量l3作为指向LinkedList

LinkedList *l3 = new LinkedList; 
... // adapt the code to use l3 appropriately 
return l3; 
+0

最后一部分解决了我的问题..虽然我自己发现了它。我有问,但是如果我分配0整数和检查我的代码中的0我会得到误报,代码可能无法正常工作。为什么将NULL分配给整数? –

+0

我的建议是提出一个新的问题,因为它与UB /崩溃无关。请不要试图改变这个问题的主题,因为它被回答/接受。你也必须更具体。 – drescherjm

+0

我已经提到我的程序应该在描述中做什么。我在两个链表中添加数字。 –

2

正如其他的评论说,你的错误是这样一个:return &l3;

l3是一个本地对象,只是该函数结束之前被删除,这样是不是dinamically分配的任何对象。这是因为LinkedList对象的范围

你应该写:

LinkedList* l3 = new LinkedList(); 
//... 
//... 
return l3; 

此功能现在返回一个指向你的对象。

注意:包含该指针的变量l3在该函数之前被删除,但它并不重要,因为对象生存期不再与该函数绑定。