C++程序在VS上运行平稳,但在Linux Mint上运行不畅

C++ program running smoothly on VS but not on Linux Mint

本文关键字:运行 但在 Linux Mint 程序 VS C++      更新时间:2023-10-16

由于某种原因,当我在VS上运行C++程序时,它会编译并顺利运行,当我试图在Linux Mint终端上运行它时,它确实编译没有任何错误,但我没有得到任何反馈/打印到终端。。。它只是卡住了——所以我甚至猜不出问题在哪里。有什么建议吗?

说到Linux,我真的是个傻瓜。。。我的程序包含2个cpp类文件、2个头文件(每个头文件对应一个类)和一个main.cpp文件,我正试图这样运行:
g++ *.cpp -o myprog
./myprog

它确实创建了一个myprog文件,但当我运行它时,什么也没发生,就像我说的那样。

我的代码:

btree.h

#include <iostream>
#ifndef _BTREE_H_
#define _BTREE_H_
class LinkedList;
struct node
{
int key_value;
node *left;
node *right;
};
class btree
{
friend class LinkedList;
public:

// Default constructor
btree();
~btree();
// Copy Constructor by list
btree(LinkedList &list);
// Copy Constructor by tree
btree(btree & bt);
// assignment operator from linked list
btree & operator=(const LinkedList & ls);
// assignment operator from tree
btree& operator=(const btree &bt);
// insert new value to binary tree
void insert(int key);
// mirror the tree
void mirror();
LinkedList* Tree2linkListbyDepth();
int getTreeDepth();
// print tree (in order)
friend std::ostream& operator<<(std::ostream& os, btree& dt);
private:
node* root;
bool isMirrored;
void copyConstructor(node *bt);
void destroyTree(node * tmp);
void insert(node* tmp, int key);
void mirrorInsert(node* tmp, int key);
void mirror(node * node);
LinkedList TreeToList(node *tmp, LinkedList *listToReturn, int depth);
int getTreeDepth(node * tmp);
friend std::ostream& travel(std::ostream & os, node* root);
};
#endif // _BTREE_H_

btree.cpp

#include"btree.h"
#include"Linkedlist.h"
#include<iostream>
using namespace std;
//constructor
btree::btree()
{
root = NULL;
isMirrored = false;
}
//destructor
btree::~btree()
{
destroyTree(this->root);
}
void btree::destroyTree(node * tmp)
{
if (tmp == NULL)
return;
destroyTree(tmp->left);
destroyTree(tmp->right);
delete(tmp);
}
//copy constructor - list to binary tree.
btree::btree(LinkedList &list)
{
while (list.head!=NULL)
{
insert(list.head->data);
list.head = list.head->next;
}
}
//copy constructor - inorder.
btree::btree(btree & bt)
{
if (bt.root == NULL)
root = NULL;
else
copyConstructor(bt.root);
}
void btree::copyConstructor(node *bt)
{
node* tmp = bt;
if (!tmp)
return;
copyConstructor(tmp->left);
insert(tmp->key_value);
copyConstructor(tmp->right);
}
//copying list to binary tree using "=" operator.
btree & btree::operator=(const LinkedList & ls)
{
Node *tmp = ls.head;
while (tmp != NULL)
{
insert(tmp->data);
tmp = tmp->next;
}
return *this;
}
//copying binary trees using "=" operator
btree & btree::operator=(const btree & bt)
{
if (this->root == bt.root) //cheking if not itself
return *this;
//למחוק את העץ הקיים
copyConstructor(bt.root);
return *this;
}
//inserting node to the binary tree
void btree::insert(int key)
{
node *tmp = root;
if (root != NULL)
{
if (isMirrored)             //checking if the tree has been mirrored
mirrorInsert(tmp, key);
else
insert(tmp, key);
}
//if the tree is empty - adding a new node  
else
{
root = new node;
root->key_value = key;
root->left = NULL;
root->right = NULL;
}
}
//regular insertion - smaller numbers to the left and bigger numbers to the right of the root.
void btree::insert(node* tmp, int key)
{
if (tmp->key_value >= key)
{
if (tmp->left == NULL)
{
tmp->left = new node();
tmp->left->key_value = key;
tmp->left->left = NULL;
tmp->left->right = NULL;
return;
}
insert(tmp->left, key);
}
else if (tmp->key_value < key)
{
if (tmp->right == NULL)
{
tmp->right = new node();
tmp->right->key_value = key;
tmp->right->left = NULL;
tmp->right->right = NULL;
return;
}
insert(tmp->right, key);
}
}
//mirrored insertion - smaller numbers to the right and bigger numbers to the left of the root.
void btree::mirrorInsert(node* tmp, int key)
{
if (tmp->key_value <= key)
{
if (tmp->left == NULL)
{
tmp->left = new node();
tmp->left->key_value = key;
tmp->left->left = NULL;
tmp->left->right = NULL;
return;
}
mirrorInsert(tmp->left, key);
}
else if (tmp->key_value > key)
{
if (tmp->right == NULL)
{
tmp->right = new node();
tmp->right->key_value = key;
tmp->right->left = NULL;
tmp->right->right = NULL;
return;
}
mirrorInsert(tmp->right, key);
}
}
//mirroring the binary tree and keeping track of it.
void btree::mirror()
{
if (isMirrored)
isMirrored = false;
else
isMirrored = true;
mirror(root);
}
void btree::mirror(node * node)
{
if (node == NULL)
return;
else
{
struct node * tmp;
mirror(node->left);
mirror(node->right);
tmp = node->left;
node->left = node->right;
node->right = tmp;
}
}
//constructing a list of lists, each list contains all the nodes at a specific level(depth).
LinkedList* btree::Tree2linkListbyDepth() 
{
if (this == NULL)
return NULL;
node *tmp = root;
LinkedList *list;
int depth = this->getTreeDepth();
list = new LinkedList[depth];       //list of lists

for (int i = 0; i < depth; i++)
{
TreeToList(tmp, &list[i],(depth-i));    //adding to list[i] all the node in (depth-i) level from the binary tree using "TreeToList"
}
return list;
}
//returning a list with all the node at a specific level (depth).
LinkedList btree::TreeToList(node *tmp, LinkedList *listToReturn, int depth)
{
if (tmp == NULL)
return *listToReturn;
else if (getTreeDepth(tmp) == depth)
listToReturn->add(tmp->key_value);
else
{
TreeToList(tmp->left, listToReturn, depth);
TreeToList(tmp->right, listToReturn, depth);
}
return *listToReturn;
}
//returning the binary tree's depth.
int btree::getTreeDepth()
{
if (this->root == NULL)
return 0;
node* tmp = root;
return getTreeDepth(tmp);
}
int btree::getTreeDepth(node * tmp)
{
if (tmp == NULL)
return 0;
int leftDepth = getTreeDepth(tmp->left);
int rightDepth = getTreeDepth(tmp->right);
if (leftDepth > rightDepth)
return leftDepth+1;
else
return rightDepth+1;
}
ostream & travel(ostream &os, node* root)
{
node* tmp = root;
if (!root)
return os;
travel(os, root->left);
os << root->key_value << ",";
travel(os, root->right);
return os;
}
//printing the binary tree inorder - using recursive function "travel".
ostream & operator<<(ostream & os, btree & dt)
{
os << "Tree: ";
travel(os, dt.root);
os << endl;
return os;
}

链接列表.h

#include <iostream>
#ifndef _LINKEDLIST_H_
#define _LINKEDLIST_H_
class btree;
class Node
{
public:
Node* next;
int data;
};
using namespace std;
class LinkedList
{
friend class btree;
public:
int length;
Node* head;
LinkedList(btree &bt);
LinkedList(LinkedList &bt);
LinkedList();
~LinkedList();

void add(int data);
LinkedList & operator=(const LinkedList & bt);
LinkedList& operator=(const btree &bt);
friend std::ostream& operator<<(std::ostream& os, LinkedList& l);
private:
void copyBtToList(struct node *bt);
LinkedList(const LinkedList &bt);
void addToTail(int data);
};
#endif // !_LINKEDLIST_H_

链接列表.cpp

#include"Linkedlist.h"
#include"btree.h"
#include<iostream>
using namespace std;
LinkedList::LinkedList() {
length = 0;
head = NULL;
}
//copy constructors.
LinkedList::LinkedList(LinkedList& other) {
length = 0;
if (this->head == other.head)
return;
Node* tmp = other.head;
while (tmp != NULL)
{
this->addToTail(tmp->data);
tmp = tmp->next;
}
length = other.length;
}
LinkedList::LinkedList(const LinkedList& other) {
this->length = other.length;
if (length == 0)
return;
Node* tmp = other.head;
while (tmp != NULL)
{
this->add(tmp->data);
tmp = tmp->next;
}
}
//destructor.
LinkedList::~LinkedList() {
Node* next = head;
Node* cur = NULL;
while (next != NULL) {
cur = next;
next = next->next;
delete cur;
}
}
//copying binary tree to a list.
LinkedList::LinkedList(btree &bt) {
if (bt.root == NULL)
this->head = NULL;
else
copyBtToList(bt.root);
}
void LinkedList::copyBtToList(node *bt)
{
node* tmp = bt;
if (!tmp)
return;

copyBtToList(tmp->left);
add(tmp->key_value);
copyBtToList(tmp->right);
}
//adding node to the head of the list.
void LinkedList::add(int data) {
Node* node = new Node();
node->data = data;
if (head == NULL) { //list is empty
head = node;
head->next = NULL;
length++;
return;
}
node->next = head;
head = node;
length++;
}
//adding node to the tail of the list.
void LinkedList::addToTail(int data) {
Node* node = new Node();
node->data = data;
node->next = NULL;
if (this->length == 0 || head == NULL) { //list is empty
head = node;
length++;
return;
}
Node* curr = head;
while (curr != NULL && curr->next!=NULL)
curr = curr->next;
curr->next = node;
length++;
}
//copying lists using "=" operator.
LinkedList & LinkedList::operator=(const LinkedList & bt)
{
LinkedList tmp(bt);
std::swap(tmp.head, this->head);
return *this;
}
//copying binary tree to list using "=" operator.
LinkedList & LinkedList::operator=(const btree & bt)
{
LinkedList tmp;
tmp.copyBtToList(bt.root);
head = tmp.head;
return *this;
}
//printing list in the form of "(x1,x2,...,xn)" using "<<" operator.
ostream & operator<<(ostream & os, LinkedList & l)
{
Node *tmp = l.head;
os << "List: (";
while (tmp != NULL)
{
os << tmp->data << ",";
tmp = tmp->next;
}
os << ")"<<endl;
return os;
}

main.cpp

#include"Linkedlist.h"
#include"btree.h"
#include<iostream>
using namespace std;
int main()
{
btree *tree = new btree();
tree->insert(10);
tree->insert(6);
tree->insert(14);
tree->insert(5);
tree->insert(8);
tree->insert(12);
tree->insert(16);
LinkedList* l = tree->Tree2linkListbyDepth();
int dp = tree->getTreeDepth();
for (int i = 0; i < dp; i++) {
cout << l[i];
}
cout << *tree;
tree->mirror();
cout << *tree;
btree *tree1 = new btree(l[dp - 1]);
cout << *tree1;
btree *tree2 = new btree(*tree1);;
tree2->insert(100);
cout << *tree1;
cout << *tree2;
LinkedList* l1 = new LinkedList(*tree1);
LinkedList* l2 = new LinkedList(*l1);
l2->add(99);
cout << *l1;
cout << *l2;
delete tree;
}

我在VS:上的输出

List: (10,)
List: (14,6,)
List: (16,12,8,5,)
Tree: 5,6,8,10,12,14,16,
Tree: 16,14,12,10,8,6,5,
Tree: 5,8,12,16,
Tree: 5,8,12,16,
Tree: 5,8,12,16,100,
List: (16,12,8,5,)
List: (99,16,12,8,5,)

顺便说一句,如果你也能检查一下我的";包括";做得很正确,因为我不可能这么容易弄明白
谢谢:)

更新:

我通过AppVerifier运行了您的代码。直到我尝试了调试/发布x86/x64版本的不同变体,它才开始找到任何东西。有一点我让它在Windows中崩溃了。然后它停止了对坠机事件的谴责。然后,我更改了所有初始的tree->insert语句,使其采用rand()值,而不是固定值,我可以使其在Windows中100%崩溃。我不确定我的事件是否需要AppVerifier,但我把它打开了。就在那时,我注意到你的LinkedList析构函数试图删除0xcccccccc处的指针,这是调试版本中未初始化的内存。

最重要的是,这是你的错误:

您的LinkedList副本构造函数没有将头指针初始化为NULL

此外,您还有两个副本构造函数。一个接受非常量引用并且是公共的。另一个(行为略有不同)采用常量引用,但却是私有的。

您只需要一个既是公共的又具有常量引用的副本构造函数。

这是解决办法。让它成为公共构造函数:

LinkedList::LinkedList(const LinkedList& other) {
length = 0;
head = NULL;  // YOU FORGOT THIS LINE
Node* tmp = other.head;
while (tmp != NULL)
{
this->addToTail(tmp->data);
tmp = tmp->next;
}
length = other.length;
}

然后删除LinkedList复制构造函数的另一个实例。

另一件看起来可疑的事情。获取链接列表的btree构造函数正在损坏您的列表它还忘记了在尝试第一次插入之前初始化对象

btree::btree(LinkedList &list)
{
while (list.head != NULL)
{
insert(list.head->data);
list.head = list.head->next;
}
}

这是完全错误的。当您从列表中构造btree(通过引用传递)时,构造函数将修改传入的LinkedList实例。当此构造函数返回时,list实例将返回给具有null头指针的调用,但当函数返回时,返回的成员长度为非零。。并且您的LinkedList析构函数将无法递归树以释放内存。因此,您同时存在内存泄漏和无效对象状态。

请改为执行此操作。

btree::btree(const LinkedList &list)
{
root = NULL;
isMirrored = false;
Node* tmp = list.head;
while (tmp != NULL)
{
insert(tmp->data);
tmp = tmp->next;
}
}

最好将初始值设定项列表与构造函数一起使用:

btree::btree(const LinkedList &list) :
root(NULL),
isMirrored(false)
{
...
}

欢迎您:)


旧东西:

您的cout语句缺少行尾标记(用于刷新输出):

而不是这样的声明:

cout << *tree;

这样做:

cout << *tree << endl;

但这不是你的问题。你的程序出现故障:

[ec2-user@ip-172-31-10-108 stackover]$ g++ main.cpp btree.cpp LinkedList.cpp
[ec2-user@ip-172-31-10-108 stackover]$ ./a.out
List: (10,)
List: (14,6,)
List: (16,12,8,5,)
Tree: 5,6,8,10,12,14,16,
Tree: 16,14,12,10,8,6,5,
Segmentation fault

看起来我们有一个导致崩溃的错误。让我们使用调试构建和分析进行编译:

[ec2-user@ip-172-31-10-108 stackover]$ g++ main.cpp btree.cpp LinkedList.cpp -g
[ec2-user@ip-172-31-10-108 stackover]$ gdb ./a.out
GNU gdb (GDB) Amazon Linux (7.6.1-64.33.amzn1)
...
Reading symbols from /home/ec2-user/stackover/a.out...done.
(gdb) run
Starting program: /home/ec2-user/stackover/./a.out
Missing separate debuginfo for /usr/lib64/libstdc++.so.6
Try: yum --enablerepo='*debug*' install /usr/lib/debug/.build-id/87/91ddd49348603cd50b74652c5b25354d8fd06e.debug
Missing separate debuginfo for /lib64/libgcc_s.so.1
Try: yum --enablerepo='*debug*' install /usr/lib/debug/.build-id/a0/3c9a80e995ed5f43077ab754a258fa0e34c3cd.debug
List: (10,)
List: (14,6,)
List: (16,12,8,5,)
Tree: 5,6,8,10,12,14,16,
Tree: 16,14,12,10,8,6,5,
Program received signal SIGSEGV, Segmentation fault.
0x00000000004011b5 in btree::mirrorInsert (this=0x614ea0, tmp=0x21, key=16) at btree.cpp:133
133         if (tmp->key_value <= key)
Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.173.amzn1.x86_64
(gdb)

简短的回答是:看起来你需要在btree.cpp的第133行进行一些额外的调试。tmp的值为0x21,这可能不是一个合法的指针值。

相关文章: