循环中对象的范围

时间:2016-07-14 03:55:48

标签: c++ c++11 vector scope breadth-first-search

我有一个简单的算法,它返回一个列表列表,其中每个内部列表包含二叉树不同级别的节点。我无法理解如何重置"我内心清单的范围(例如见下文)。

我的树是一棵简单的玩具树,如下:

struct Node {
    int data;
    Node *left, *right;
}

我使用一个简单的bfs,它应该返回一个列表列表。我尝试在每个循环上创建一个新列表,但我不确定如何清除"列表并开始一个新的。

std::vector< std::vector<Node *> > build_lists(Node *root) {
    std::vector< std::vector<Node *> > result;

    Node *newline = new Node { std::numeric_limits<int>::min(), nullptr, nullptr };

    std::deque<int> q;
    q.push_back(root);
    q.push_back(newline);


    Node *tmp;
    std::vector<Node *> inner;    // HERE IS WHERE IS SET THE FIRST INNER VECTOR
    while(!q.empty()) {
        tmp = q.front();
        q.pop_front();
        if (tmp == newline) {
            result.push_back(inner);
            std::vector<Node *> inner; // HERE IS WHERE I TRY TO ''RESET'' THE VECTOR
            if (!q.empty())
                q.push_back(newline);
        } else {
            inner.push_back(tmp);
            if (tmp->left)
                q.push_back(tmp->left);
            if (tmp->right)
                q.push_back(tmp->right);
        }
    }
}

显然,我无法理解范围和一些基本语言功能。如果有人能帮助我指出正确的方向,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

您无法通过再次声明变量来重置变量,这正是您的代码正在执行的操作。您现在有一个具有相同名称的第二个变量,在第二个变量的持续时间内,该名称指向第二个变量。

相反,您需要使用方法来清除第一个变量。

vector确实有method to reset it's contents - vector::clear

你应该这样做:

result.push_back(inner);
// std::vector<Node *> inner;
inner.clear();

如果你需要清除你已经推入向量内的东西,你可以这样做:

vector< vector< int > > vvi;
vector< int > vi;
vi.push_back(1); // fill
vii.push_back(vi); // vii has a copy of vi as it is now.
auto & _v = vii[0]; // fetch a reference to the copy
_v.clear(); // clear it
vii[0].clear(); // same in one step
assert( vii[0].size() == 0 ); // still contains a vector at index 0 but it's empty

尽管您要清除指针的向量 - 正如其他人指出的那样(ha),您需要非常小心,不要“忘记”指针。

例如,这会很糟糕:

vector< int* > x;
x.push_back( new int(4) );
x.clear(); // leak

答案 1 :(得分:0)

为了使对象超出范围,必须创建 INSIDE 循环,例如:

while(1) {
  std::vector<int> v;
  ...
  // at that point 'v' will go out of scope and thus destroyed
}

但是,当你这样做时:

std::vector<int> v;
while(1) {
  ...
  // 'v' is always the same at this point
}

您可以使用std::vector::clear()重置矢量,但要小心,因为您正在使用指针。除非你跟踪指向的对象,否则只需清除向量就会导致悬空指针,从而未定义的行为,你不希望这种情况发生。

如果你需要释放指针指向的内存,那么你应该首先删除指针指向的对象,然后然后清除向量。