C++ 指针向量有效/正确迭代

C++ 指针向量有效/正确迭代,c++,multithreading,pointers,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 }; st

迭代指针向量的正确方法是什么? 它将“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);
        }
    }
}
#包括
#包括
#包括
int ints[]={1,7,8,4,5,10,15,22,50,29};
std::向量intptrs;
void iterate();
int main()
{
for(整数i:整数)
{
输入。推回(&i);
}
向量期货;
futures.push_back(std::async(iterate));
futures.push_back(std::async(iterate));
适用于(汽车和燃油:期货)
{
f、 get();
}
系统(“暂停”);
}
void iterate()
{
对于(std::vector::iterator it=intptrs.begin();it!=intptrs.end();+it;)
{
如果(**it>5)
{
一个错误是

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

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

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

对向量进行迭代并删除某些元素的传统习惯用法如下所示:

for(auto i = somevec.begin(); i != somevec.end();) {
    if (some condition) {
        i = somevec.erase(i);
    }
    else {++i;}
}
请注意,
++i
不在for循环头中,它在循环体中,只有在我们不擦除的情况下才会发生。从向量中擦除某些内容时返回的迭代器是如果改为
++i
'd将得到的迭代器,因此您将跳过元素并递增
somevec.end()
如果您以最初编写代码的方式编写代码


(您的代码打印“29”的原因是,您正在调用未定义的行为,方法是取消引用一个指向已销毁的自动的指针。在您的实现中,它仍然具有它所保留的最后一个值。)

你不能
删除
你没有
新建的
。你是
新建的
那些
int
吗?然后不要
删除它们。只要使用
std::vector
并使用“擦除-删除习惯用法”。此外,您存储的不是指向
ints
中的值的指针,而是指向for循环创建的局部变量的指针,这些变量在循环后超出了范围。您也有错误。如果您想询问有关性能的问题,您需要提供有关所涉及类型的详细信息,否则您将得到不相关的建议。此外,一般来说,避免使用裸指针的STL容器-一般来说,最好在容器中使用std智能指针。在大多数情况下,最简单的方法可能是使用std::vector.Awesome!更新的代码是否有其他问题?或者效率是否有任何提高?您使用异步是不正确的。您没有在向量上同步,因此有可能
iterate()
的一个异步实例删除迭代器,而另一个实例正在对向量执行操作。您可能希望更清楚地了解您实际想要异步执行的操作;您当前采用的方法只会导致一个锁保护向量和两个iterate()实例如果向量的每个元素的处理可能需要很长的时间,考虑为向量的每个未擦除的元素旋转线程,而不是在一个向量上运行多个线程。因此,技术上我所拥有的是线程安全的,但不会带来任何效率的提高吗?你是说我应该开始一个新的线程吗?线程将每个有效元素作为优化来处理?我是说它不是线程安全的,而使它成为线程安全的最简单方法(使用互斥体访问向量)只会给您带来效率增益,即主线程可以在两次调用iterate()时做其他不涉及向量的事情处理向量。如果您希望同时处理多个元素,那么将异步行为转移到循环内部(例如
或者{std::async(process,*i);++i;}
)可能更明智。