gpt4 book ai didi

c++ - 使用 cerr 修复的链表段错误

转载 作者:太空宇宙 更新时间:2023-11-04 16:17:43 26 4
gpt4 key购买 nike

我有以下代码。这段代码的作用是合并两个排序的链表,然后删除两个链表并返回一个新列表:

#include <iostream>

using namespace std;

class node {
public:
node(int, node*);
node* get_next() const;
void set_next(node*);
int get_item() const;
void set_item(int);
private:
int item;
node* next;
};

node* clone_and_destroy(node* a)
{
node* new_list;
node* prev;
node* ret_val;
while ( a )
{
new_list = new node(a->get_item(),NULL);
if ( prev ){
prev->set_next(new_list);
prev = prev->get_next();
}
else{
prev = new_list;
ret_val = prev;
}
node* temp = a;
a = a->get_next();
delete temp;
}
return ret_val;
}

node* merge(node*& a, node*& b){
if ( !a ){// cerr<<"\r";
return clone_and_destroy(b);}
if ( !b )
return clone_and_destroy(a);

node* smaller_node, *bigger_node;
if ( a->get_item() < b->get_item() ){
smaller_node = a;
bigger_node = b;
}
else {
smaller_node = b;
bigger_node = a;
}
node* next_node = smaller_node->get_next();
node* merged_list = new node(smaller_node->get_item(),smaller_node->get_next());
delete smaller_node;
merged_list->set_next(merge(next_node,bigger_node));
a = NULL ;
b = NULL ;
return merged_list;
}

/*node* merge(node*& a, node*& b){
if ( !a )
return b;
if ( !b )
return a;
if ( a->get_item() < b->get_item() ){
node* a_next = a->get_next();
node* merged_list = a;
merged_list->set_next(merge(a_next,b));
delete a;
return merged_list;
}
else {
node* b_next = b->get_next();
node* merged_list = b;
merged_list->set_next(merge(a,b_next));
delete b;
return merged_list;
}
}*/

void print(node* a)
{
while ( a )
{
cout << a->get_item() << " ";
a = a->get_next();
}
cout << endl;
}

node::node(int _item, node* _next)
{
item = _item;
next = _next;
}
node* node::get_next() const
{
return next;
}
void node::set_next(node* new_next)
{
next = new_next;
}
int node::get_item() const { return item; }
void node::set_item(int _item)
{
item = _item;
}

int main() {
node* l1 = NULL, *l2 = NULL;
cout << "Before Merging: " << endl;
for (int i = 5; i > 0; i--) {
l1 = new node(i, l1);
l2 = new node(2*i-3, l2);
}
cout << "List 1 is: \t\t";
print(l1);
cout << endl;
cout << "List 2 is: \t\t";
print(l2);
cout << endl << "After Merging:" << endl;
node* m = merge(l1, l2);
cout << "List 1 is: \t\t";
print(l1);
cout << "Should be: \t\t[ ]" << endl;
cout << endl;
cout << "List 2 is: \t\t";
print(l2);
cout << "Should be: \t\t[ ]" << endl;
cout << endl;
cout << "Merged List is: \t";
print(m);
cout << "Should be: \t\t[ -1 1 1 2 3 3 4 5 5 7 ]" << endl;


for (node* h = m; h != NULL; h = m) {
m = m->get_next();
delete h;
}
return 0;
}

代码的重要部分是合并功能,其余只是实现此功能的工具。现在有趣的事情发生了!这段代码在我运行时出现段错误,但是当我尝试调试我的代码时,我在合并函数的第一行使用了 cerr(它被注释)并且突然它工作正常!有人可以给我解释一下吗!?这个 cerr 在做什么?!以及如何在没有此 cerr 并且对代码进行最少更改的情况下修复我的代码!?现在我知道 cerr 会阻止 couts 缓冲,但我认为这里不是这种情况!

最佳答案

*prev 没有初始化任何东西,你正试图访问它。因此段。错误。

node* clone_and_destroy(node* a) { .. ..

if ( prev ){

编辑:初始化它将无效修复段错误。但你检查它背后的逻辑。

node* prev = NULL;

Edit2:为什么 cerr 修复段错误

Code crashes unless I put a printf statement in it

它的摘要“这个问题问“为什么 printf() 语句‘修复’了东西”。答案是因为它转移了问题。你有一个 Heisenbug,因为分配的内存被滥用,并且printf() 的存在设法稍微改变了代码的行为。”

关于c++ - 使用 cerr 修复的链表段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20783775/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com