我的C ++程序仅以Xcode返回EXC_BAD_ACCESS

时间:2018-10-13 14:28:35

标签: c++ xcode

我制作了一个涉及二叉搜索树的程序。基本上,我将一组输入整数分成“箱”,以使每个箱的内容求和时它们的值相等。

#include <iostream>
#include <vector>

#ifndef DEBUG
#define DEBUG 0
#endif

using namespace std;

class Node {
private:
    int weight = 0;
    Node* leftNode;
    Node* rightNode;
    int bin = 0;
public:
    Node() {}

    Node(int weight) {
        this->weight = weight;
    }

    void printContents() {
        cout << weight << " ";
        if(leftNode) leftNode->printContents();
        if(rightNode) rightNode->printContents();
    }

    void addNode(Node* node) {
        if(node->getWeight() <= this->weight) {
            if(leftNode) leftNode->addNode(node);
            else leftNode = node;
        } else {
            if(rightNode) rightNode->addNode(node);
            else rightNode = node;
        }
    }

    Node* getNode(int weight) {
        if(!hasChildren()) {
            if(this->weight == weight && bin == 0) return this;
            else return nullptr;
        } else {
            Node* n = nullptr;
            if(this->weight == weight && bin == 0) {
                n = this;
            }
            Node* child;
            if(leftNode && weight <= this->weight) {
                child = leftNode->getNode(weight);
            } else if(rightNode && weight > this->weight) {
                child = rightNode->getNode(weight);
            } else {
                child = nullptr;
            }
            if(child) {
                return child;
            }
            else return n;
        }
    }

    bool hasChildren() {
        if(leftNode || rightNode) return true;
        else return false;
    }

    int getWeight() {
        return weight;
    }

    void setBin(int bin) {
        this->bin = bin;
    }

    int getBin() {
        return bin;
    }

    void unbin() {
        bin = 0;
    }

    void operator=(Node* node) {
        this->weight = node->weight;
        this->leftNode = node->leftNode;
        this->rightNode = node->rightNode;
        this->bin = node->bin;
    }
};

class Bin {
private:
    int binNum = 0;
    int weight = 0;
    int targetWeight = 0;
    vector<Node*> nodes;
public:
    Bin(int binNum, int targetWeight) {
        this->binNum = binNum;
        this->targetWeight = targetWeight;
    }

    void addNode(Node* node) {
        weight += node->getWeight();
        node->setBin(binNum);
        nodes.push_back(node);
    }

    Node* removeLatestNode() {
        Node* n = nodes.back();
        weight -= n->getWeight();
        nodes.pop_back();
        n->unbin();
        return n;
    }

    int getWeight() {
        return weight;
    }

    bool isFull() {
        if(weight == targetWeight) return true;
        else return false;
    }

    bool willBeOverloaded(int x) {
        if(weight + x > targetWeight) return true;
        else return false;
    }
};

void organize(Node* rootNode, int bins, int weightPerBin) {
#if DEBUG
    cout << "Weight per bin: " << weightPerBin << endl;
#endif
    for(int i = 1; i <= bins; i++) {
        Bin bin(i, weightPerBin);
        int x = weightPerBin;
        while(!bin.isFull()) {
            while(x > 0) {
                Node* n = rootNode->getNode(x);
                if (n) {
#if DEBUG
                    cout << "bin " << i << " : ";
                    cout << n->getWeight() << endl;
#endif
                    if (!bin.willBeOverloaded(n->getWeight())) {
#if DEBUG
                        cout << "adding to bin " << i << " : " << n->getWeight() << endl;
#endif
                        bin.addNode(n);
                        x = weightPerBin - bin.getWeight();
                        if(bin.isFull()) break;
                    } else {
                        x--;
                    }
                } else {
                    x--;
                }
            }
            if(!bin.isFull()) {
                Node* n = bin.removeLatestNode();
#if DEBUG
                cout << "removing from bin " << i << " : " << n->getWeight() << endl;
#endif
                x = n->getWeight() - 1;
            }
        }
    }
}

int getWeightPerBin(int* weights, int n, int bins) {
    int weight = 0;
    for(int i = 0; i < n; i++) {
        weight += weights[i];
    }
    return weight/bins;
}

int main() {
    int n;
    int *weights;
    int bins;

    cin >> n;

    weights = new int[n];

    for(int i = 0; i < n; i++)
        cin >> weights[i];
    cin >> bins;

    Node nodes[n];
    nodes[0] = new Node(weights[0]); //the root node
    for(int i = 1; i < n; i++) {
        nodes[i] = new Node(weights[i]);
        nodes[0].addNode(&nodes[i]);
    }

    organize(&nodes[0], bins, getWeightPerBin(weights, n, bins));

    for(int i = 0; i < n; i++) {
        cout << nodes[i].getBin() << " ";
    }

    return 0;
}

我在CLion IDE中开发了该程序,它运行完美。最近,我发现Xcode也可以用于开发C ++程序,因此我尝试将其与完全相同的代码一起使用。但是当我运行该程序时,它总是返回:

xcode error screenshot

它返回一个名为EXC_BAD_ACCESS的错误,这是我第一次遇到该错误。我是一名具有Java良好背景的学生,目前正在为课程学习C ++。我对C ++的了解有限,我想知道这个问题是由于Xcode还是由于我的代码固有

1 个答案:

答案 0 :(得分:0)

您无需初始化leftNoderightNode-它们不是 神奇地初始化为nullptr,因此调用类似

的函数
void printContents() {
    cout << weight << " ";
    if(leftNode) leftNode->printContents();
    if(rightNode) rightNode->printContents();
}

将具有未定义的行为。

我建议您在使用变量之前先对其进行初始化。