我不明白为什么以下不起作用:
queue<int*> q;
int counter = 1;
for (int i = 0; i < 3; i++) {
int a[1] = {counter};
q.push(a);
counter++;
}
while (!q.empty()) {
int *top = q.front();
q.pop();
cout << top[0] << endl;
}
应该打印出来:1 2 3,而是打印出3 3 3。这是因为每次运行循环后队列中的指针都是相同的。为什么会这样?
答案 0 :(得分:8)
您正在存储指向局部变量的指针,并在它们指向的局部变量超出范围之后使用这些指针。
换句话说:您正在调用Undefined Behavior。
结果:不应打印出“1 2 3”。它不需要做任何事情,并允许做任何它喜欢的事情。 “3 3 3”对我来说似乎很合理,因为它也可以崩溃。
答案 1 :(得分:4)
int a[1] = {counter};
q.push(a);
不正确。它调用未定义的behvaiour,因为花括号(for-loop块)之外不存在a
。即使它是明确定义的,你的代码还有另一个问题,queue
中的所有项都是相同的,因为a
(相同的内存)在循环中重复使用。
解决方案是:
int *a = new int[1];
a[0] = counter;
q.push(a);
如果你这样做,那么你当然要自己解除记忆。
但我想知道queue
中的每个项目是否只有一个int
,那么为什么不使用以下内容:
queue<int> q;
for (int i = 0; i < 3; i++)
{
q.push(counter);
counter++;
}
或者如果你真的想要数组,那么为什么不使用std::queue<std::vector<int> >
:
std::queue<std::vector<int> > q;
for (int i = 0; i < 3; i++)
{
std::vector<int> v;
v.push_back(counter);
q.push(v); //dont worry - a copy of the vector is being pushed!
counter++;
}
通过这种方式,您不必处理原始指针。您不必自己分配或释放内存,我认为这是一种安全的方法!
答案 2 :(得分:3)
您有未定义的行为,因为您将a
的声明超出了您将其推入队列的循环结束范围。
可能发生的事情是a
的内存位置每次都被重用,但绝对没有保证。下次运行它时可能会得到不同的输出,或者你可能会崩溃,或者恶魔可能飞出你的鼻孔。
答案 3 :(得分:1)
如果您坚持使用指向整数的指针,则以下代码可以执行您想要的操作:
#include <queue>
#include <iostream>
int main()
{
std::queue<int*> q;
int counter = 1;
for (int i = 0; i < 3; i++) {
int* a = new int;
*a = counter;
q.push(a);
counter++;
}
while (!q.empty()) {
int *top = q.front();
q.pop();
std::cout << *top << std::endl;
delete top;
}
return 0;
}