循环中对象的作用域

Scope of an Object in a Loop

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

我的树是一棵简单的玩具树,像这样:

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

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

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);
        }
    }
}

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

您不能通过再次声明来重置变量,这是您的代码正在做的事情。您现在有第二个同名变量,在第二个变量的持续时间内,该名称指向第二个变量。

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

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) 你需要非常小心不要 'lose track' 指针.

例如,这会很糟糕:

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

为了使对象超出范围,必须在 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() 来重置向量,但要小心,因为您使用的是指针。除非您跟踪指向的对象,否则仅清除向量会导致 悬空指针 ,因此 未定义的行为 而您不希望这样发生了。

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