使用集合交集的意外向量行为
Unexpected vector behavior using set intersection
我正在尝试将一个二维向量与另一个二维向量进行比较。
vector<vector<int> >::iterator rowit1;
for(rowit1 = aboveaveperms.begin(); rowit1 != aboveaveperms.end();rowit1++)
{
vector<vector<int> >::iterator row2it;
int s = 0;
for(row2it = afterave.begin(); row2it != afterave.end();row2it++)
{
vector<int> matches (9);
vector<int>::iterator itset;
itset = set_intersection(rowit1->begin(),rowit1->end(),row2it->begin() + 1,row2it->end(),matches.begin());
matches.resize(itset-matches.begin());
s = matches.size();
matches.erase(matches.begin(),matches.end()); // my attempt at trying to correct it
}
}
在第一遍的第二个循环中,正确创建了包含 9 个零的匹配项。但是一旦它开始第二个循环,一旦它到达花括号,它就会得到 1.01 亿而不是 9。一旦它真正到达它的声明,它就会回到正确的 9。我在调试时注意到它包含我正在检查的所有二维向量,然后声明将其更正为仅包含 9 个整数。
idzireit
附录:
正如有人指出的那样,我忘了问我的问题。上面的代码确实可以正常工作,因为我想要匹配的数量(5 到 9 之间),但是由于向量的不稳定行为,如果其他向量变得太大,它会导致内存泄漏或 sigseg 吗?
另外,正如 whozcraig 所问,我有 row2it->begin() + 1 因为第一个元素是游戏编号,它比其余数字大得多。不过,其余数字已排序。
我正在尝试做的示例如下:
烫发矢量 1
1 3 5 6 7
与 4 个向量进行比较并计算每个向量中的匹配数
5 8 9 10 11
3 7 11 14 18
1 5 6 7 8
所以在 运行 循环中,第一个匹配项应该是 1,第二个应该是 2,第三个应该是 4。希望这有助于阐明我正在尝试做的事情。
附录 2:
现在我已经启动了 windoze 机器 运行ning 并在其上重新安装了 qt creator 我有 运行 上面的代码并且在 windows 上工作正常。我没有像在 ubuntu 下 运行ning 时那样得到 1.01 亿个元素。为什么它在 windoze 上可以正常工作而不是 ubuntu?
idzireit
首先,根据https://en.cppreference.com/w/cpp/algorithm/set_intersection,两个相交的向量必须排序.
其次,您将矢量 matches
的初始大小设置为 9,但如果相交元素的数量大于 9,则 std::set_intersection 超出了 [=11= 的范围], 这可能会导致未定义的行为。
您可以使用内存分析器作为 Valgrind 来执行您的代码,以检测可能的内存泄漏。您可以使用 std::back_inserter
来避免这个问题:
#include <iterator> // std::back_inserter
vector<int> matches;
std::back_insert_iterator<std::vector<int> > itset(matches);
itset = set_intersection(rowit1->begin(),rowit1->end(),row2it->begin() + 1,row2it->end(), std::back_inserter(matches));
我正在尝试将一个二维向量与另一个二维向量进行比较。
vector<vector<int> >::iterator rowit1;
for(rowit1 = aboveaveperms.begin(); rowit1 != aboveaveperms.end();rowit1++)
{
vector<vector<int> >::iterator row2it;
int s = 0;
for(row2it = afterave.begin(); row2it != afterave.end();row2it++)
{
vector<int> matches (9);
vector<int>::iterator itset;
itset = set_intersection(rowit1->begin(),rowit1->end(),row2it->begin() + 1,row2it->end(),matches.begin());
matches.resize(itset-matches.begin());
s = matches.size();
matches.erase(matches.begin(),matches.end()); // my attempt at trying to correct it
}
}
在第一遍的第二个循环中,正确创建了包含 9 个零的匹配项。但是一旦它开始第二个循环,一旦它到达花括号,它就会得到 1.01 亿而不是 9。一旦它真正到达它的声明,它就会回到正确的 9。我在调试时注意到它包含我正在检查的所有二维向量,然后声明将其更正为仅包含 9 个整数。
idzireit
附录:
正如有人指出的那样,我忘了问我的问题。上面的代码确实可以正常工作,因为我想要匹配的数量(5 到 9 之间),但是由于向量的不稳定行为,如果其他向量变得太大,它会导致内存泄漏或 sigseg 吗? 另外,正如 whozcraig 所问,我有 row2it->begin() + 1 因为第一个元素是游戏编号,它比其余数字大得多。不过,其余数字已排序。 我正在尝试做的示例如下:
烫发矢量 1
1 3 5 6 7
与 4 个向量进行比较并计算每个向量中的匹配数
5 8 9 10 11
3 7 11 14 18
1 5 6 7 8
所以在 运行 循环中,第一个匹配项应该是 1,第二个应该是 2,第三个应该是 4。希望这有助于阐明我正在尝试做的事情。
附录 2:
现在我已经启动了 windoze 机器 运行ning 并在其上重新安装了 qt creator 我有 运行 上面的代码并且在 windows 上工作正常。我没有像在 ubuntu 下 运行ning 时那样得到 1.01 亿个元素。为什么它在 windoze 上可以正常工作而不是 ubuntu?
idzireit
首先,根据https://en.cppreference.com/w/cpp/algorithm/set_intersection,两个相交的向量必须排序.
其次,您将矢量 matches
的初始大小设置为 9,但如果相交元素的数量大于 9,则 std::set_intersection 超出了 [=11= 的范围], 这可能会导致未定义的行为。
您可以使用内存分析器作为 Valgrind 来执行您的代码,以检测可能的内存泄漏。您可以使用 std::back_inserter
来避免这个问题:
#include <iterator> // std::back_inserter
vector<int> matches;
std::back_insert_iterator<std::vector<int> > itset(matches);
itset = set_intersection(rowit1->begin(),rowit1->end(),row2it->begin() + 1,row2it->end(), std::back_inserter(matches));