矢量指针高效/正确迭代

时间:2015-11-27 02:53:15

标签: c++ multithreading pointers

迭代指针向量的正确方法是什么? 这打印“29”十次,所需的输出是“7,8,10,15,22,50,29”

非常感谢!

编辑:感谢您指出最初的错误。出于某种原因,这个例子甚至可以用于多线程,但我的程序中的代码却没有。如果你发表答案,我会接受。

#include <future>
#include <vector>
#include <iostream>

int ints[] = { 1, 7, 8, 4, 5, 10, 15, 22, 50, 29 };
std::vector<int*> intptrs;
void iterate();

int main()
{
    for (int i : ints)
    {
        intptrs.push_back(&i);
    }
    std::vector<std::future<void>> futures;

    futures.push_back(std::async(iterate));
    futures.push_back(std::async(iterate));

    for (auto &f : futures)
    {
        f.get();
    }
    system("pause");
}

void iterate()
{
    for(std::vector<int*>::iterator it = intptrs.begin(); it != intptrs.end(); ++it;)
    {
        if (**it > 5)
        {
            std::cout << **it << std::endl;
            //Do stuff
        }
        else
        {
            delete (*it);
            it = intptrs.erase(it);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

错误就是

for (int i : ints)
{
    intptrs.push_back(&i);
}

应该是

for (int &i : ints)
{
    intptrs.push_back(&i);
}

原因?在前者中,i是一个局部变量(依次获取每个数组元素的副本),因此&i为您提供了一个指向局部变量的指针。你得到一个充满相同指针副本的向量...一旦循环结束,该指针就变为无效。在后者中,您实际上获得了对数组元素的引用。

答案 1 :(得分:1)

迭代向量并删除一些元素的传统习语如下所示:

for(auto i = somevec.begin(); i != somevec.end();) {
    if (some condition) {
        i = somevec.erase(i);
    }
    else {++i;}
}

请注意,++i不在for循环标题中,它位于循环体中,只有在我们不删除时才会发生。当你从向量中删除某些东西时返回的迭代器就是你++i代替你会得到的迭代器,所以你最终会跳过元素并递增somevec.end()如果你以最初编写代码的方式编写代码。

(你的代码打印的原因&#39; 29&#39;是因为你通过解除引用一个已被销毁的汽车的指针来调用未定义的行为。在你的实现中,事实证明它是&#39;仍然有它持有的最后一个值。)