在弄乱指针矢量时,我偶然发现了这个奇怪的错误:
mwe.cpp
:
#include <iostream>
#include <vector>
class A {
public:
int x = 42; // making this unsigned causes output to be only positive
int y; // removing this makes bug disappear
};
class B {
public:
B(std::vector<A *> pt_vec) {
std::cout << pt_vec[0]->x << std::endl;
};
};
int main() {
std::vector<A *> pt_vec;
A a; // these 3 lines can
std::vector<A> vec; // be replaced with
vec.push_back(a); // std::vector<A> vec {A()};
// the bug will still appear
for (A el: vec) { // doing this without for (or
pt_vec.push_back(&el); // with iterators/good ol' for)
} // makes bug disappear
B b = B(pt_vec);
//exit(1); // uncommenting this makes bug disappear
}
如何复制:
$ gcc --version
gcc (Gentoo 9.2.0-r2 p3) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -O0 -Wall -Wpedantic mwe.cpp -o mwe
mwe.cpp: In function ‘int main()’:
mwe.cpp:27:5: warning: variable ‘b’ set but not used [-Wunused-but-set-variable]
27 | B b = B(pt_vec);
| ^
(Bug在ARCH上也与GCC 9.2.0一起复制,但是Apple clang 11.0.0给出了预期的输出)
预期输出:
$ ./mwe
42
实际输出:
$ ./mwe
1533476528
$ ./mwe
-1607700816
$ ./mwe
<insert random huge number here>
我是否会在不经意间引入未定义行为?如果没有,为什么这不能按预期工作?
答案 0 :(得分:4)
for (A el: vec)
表示您正在迭代时在vec
中创建每个元素的副本。 &el
将是指向将在迭代结束时消失的对象的指针。
您想使用for (A& el: vec)
通过引用遍历vec
的元素。 &el
将成为vec
内部实际元素的指针。