我一直在用C ++实现合并排序数组问题,并发现我的代码中发生了一些奇怪的事情。所以,这是我的代码。
#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;
}
此代码将出现运行时错误。当我在codeblocks中调试它时,我在类Solution中发现了一切正常。当涉及到main函数时,while循环,发生了异常! x指向一个循环后的某个奇怪地址。 我想知道出了什么问题。
答案 0 :(得分:2)
此处,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;
}
您在堆上使用new
创建的所有其他节点,但是在此处您在堆栈上创建newNode
。它是您正在构建的列表的第一个节点,它是mergeTwoLists
的局部变量。当控制传递出函数时,第一个节点超出范围。然后,您可以访问它并在next
中取消引用main
,这是未定义的行为。
答案 1 :(得分:0)
尝试使用此
while (x->next != NULL)
答案 2 :(得分:0)
我遇到的第一个问题是,你可以保留地址来堆叠已分配的变量:
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
这是您的代码出了问题。
与ListNode
实现的链接列表通常使用动态分配的节点实现。你也应该在这里尝试一下。我建议您在合并之前为链接列表(插入,删除,搜索)实现最基本的算法,这样您就更有可能摸索出这种结构。