简体   繁体   English

以下合并排序数组C ++代码有什么问题?

[英]What's wrong in the following merging sorted array C++ code?

I have been implementing a merging sorted array problem in C++, and found something strange happened in my code. 我一直在C ++中实现合并排序数组问题,发现我的代码中发生了奇怪的事情。 So, here is my code. 所以,这是我的代码。

#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x): val(x), next(NULL) {}
};

class Solution {
public:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
        if (l1 == NULL)
            return l2;
        else if (l2 == NULL)
            return l1;
        else
        {
            ListNode *head, *p;
            ListNode *h1 = l1;
            ListNode *h2 = l2;
            if (h1->val <= h2->val)
            {
                ListNode newNode(h1->val);
                head = &newNode;
                h1 = h1->next;
            }
            else
            {
                ListNode newNode(h2->val);
                head = &newNode;
                h2 = h2->next;
            }
            p = head;
            while (h1 != NULL && h2 != NULL)
            {
                if (h1->val <= h2->val)
                {
                    ListNode *Node = new ListNode(h1->val);
                    p->next = Node;
                    //p = p->next;
                    h1 = h1->next;
                }
                else
                {
                    ListNode *Node = new ListNode(h2->val);
                    p->next = Node;
                    //p = p->next;
                    h2 = h2->next;
                }
                p = p->next;
            }
            if (h2 != NULL)
            {
                while (h2 != NULL)
                {
                    ListNode *Node = new ListNode(h2->val);
                    p->next = Node;
                    p = p->next;
                    h2 = h2->next;
                }
            }
            else if (h1 != NULL)
            {
                while (h1 != NULL)
                {
                    ListNode *Node = new ListNode(h1->val);
                    p->next = Node;
                    p = p->next;
                    h1 = h1->next;
                }
            }
            return head;
        }
    }
};

int main()
{
    ListNode A1(1);
    ListNode A2(2);
    ListNode A3(3);
    ListNode A4(5);
    ListNode A5(7);
    A1.next = &A2;
    A2.next = &A3;
    A3.next = &A4;
    A4.next = &A5;
    ListNode B1(2);
    ListNode B2(4);
    ListNode B3(6);
    ListNode B4(8);
    ListNode B5(10);
    B1.next = &B2;
    B2.next = &B3;
    B3.next = &B4;
    B4.next = &B5;
    Solution solution;
    ListNode *x = solution.mergeTwoLists(&A1, &B1);
    while (x != NULL)
    {
        cout << x->val << endl;
        x = x->next;
    }
    return 0;
}

This code will get a runtime error. 此代码将获得运行时错误。 When I debugged it in codeblocks, I found everything normal in class Solution.When it comes to main function, the while loop, something abnormal happened! 当我在代码块中调试它时,我在Solution类中发现了所有正常的东西。当涉及到主函数while循环时,发生了一些异常! x points to some strange address after one loop. x在一个循环后指向某个奇怪的地址。 I'm wondering what's wrong. 我想知道怎么了。

Here, in mergeTwoLists : 在这里,在mergeTwoLists

    if (h1->val <= h2->val)
    {
        ListNode newNode(h1->val);
        head = &newNode;
        h1 = h1->next;
    }
    else
    {
        ListNode newNode(h2->val);
        head = &newNode;
        h2 = h2->next;
    }

All of the other nodes you create on the heap with new , but here you create newNode on the stack. 您使用new在堆上创建的所有其他节点,但是在这里您在堆栈上创建了newNode It's the first node of the list you're building, and it's a local variable of mergeTwoLists . 它是您要构建的列表的第一个节点,并且是mergeTwoLists的局部变量。 When control passes out of the function, that first node passes out of scope. 当控制权超出功能范围时,该第一个节点将超出范围。 Then you access it and dereference its next in main , which is undefined behavior . 然后访问它并取消引用main next ,这是未定义的行为

试试这个

while (x->next != NULL)

Thé first problem I see un jour code is that you keep adresses to stack allocated variables: 我看到的第一个问题是代码,您需要保留地址以堆叠分配的变量:

ListNode *head, *p;
// ...
if (h1->val <= h2->val) {
   ListNode newNode(h1->val);
   head = &newNode;
   h1 = h1->next;
   // newNode is destroyed here
   // thus head now points to invalid
   // data
} else {
   // same kind of code
}
p = head;
// p does not point to anything useful

This is what's wrong with your code. 这是您的代码有问题的地方。

Linked lists like the one you are implementing with ListNode are typically implemented using dynamically allocated nodes. 像使用ListNode实现的链接列表一样,链接列表通常是使用动态分配的节点实现的。 You should try it here too. 您也应该在这里尝试。 I suggest that you implement the most basic algorithms for your linked list (insertion, removal, search) before the merge, thus you'll be more likely to grope this structure. 我建议您在合并之前为链表(插入,删除,搜索)实现最基本的算法,这样您就更有可能掌握这种结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM