C ++程序可以在VS上顺利运行,但不能在Linux Mint上运行

时间:2019-01-20 19:05:22

标签: c++ visual-studio linuxmint

由于某种原因,当我在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;
}

Linkedlist.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_

Linkedlist.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,)

顺便说一句-如果您也可以检查我的“包含”操作是否正确,因为我无法如此轻松地找出答案,我会很高兴...
谢谢:)

1 个答案:

答案 0 :(得分:2)

更新

我通过AppVerifier运行了您的代码。直到我尝试了Debug / Release x86 / x64版本的其他变体之前,它什么都没找到。有一点我使它在Windows中崩溃。然后它停止了对崩溃的谴责。然后,我将所有初始tree->insert语句更改为一个rand()值,而不是一个固定值,在Windows中我可能会使其崩溃100%。我不确定事件是否需要AppVerifier,但我仍将其保留。从那时起,我注意到您的LinkedList析构函数试图删除0xcccccccc处的指针,该指针是调试版本中的未初始化内存。

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

您的LinkedList复制构造函数未初始化指向NULL的头指针

此外,您有两个副本构造函数。它采用非const引用并且是公共的。另一个(行为稍有不同)采用const引用,但是是私有的。

您只需要一个既是公共的又带有const引用的副本构造器。

解决了。让它成为公共构造函数:

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实例将使用空的头指针返回到调用,但函数返回时将返回一个非零长度的成员。并且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-可能不是合法的指针值。