C++ 指针向量有效/正确迭代
迭代指针向量的正确方法是什么? 它将“29”打印十次,所需输出为“7、8、10、15、22、50、29” 非常感谢 编辑:感谢您指出最初的错误。出于某种原因,这个示例甚至可以使用多线程,但我程序中的代码却不能。如果你给我一个答复,我会接受的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
#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;}
)可能更明智。