stl 容器和指针的奇怪行为

发布于 2024-11-09 09:24:18 字数 348 浏览 0 评论 0 原文

我不明白为什么以下不起作用:

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。这是因为每次循环后队列中的指针都是相同的。为什么会发生这种情况?

I don't understand why the following does not work:

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;
}

It should print out: 1 2 3, but instead 3 3 3 is printed out. This is because the pointers in the queue are all the same after each run through the loop. Why does that happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暮凉 2024-11-16 09:24:18

您正在存储指向局部变量的指针,并在它们指向的局部变量超出范围后使用这些指针。

换句话说:您正在调用未定义行为

结果:它不应该打印出“1 2 3”。它不必做任何事,可以做任何它喜欢做的事。 “3 3 3”对我来说似乎很合理,因为它也允许崩溃。

You are storing pointers to local variables and using those pointers after the local variables they point to have gone out of scope.

In other words: you are invoking Undefined Behavior.

Result: It should not print out "1 2 3". It doesn't have to do anything and is allowed to do whatever it likes. "3 3 3" seems reasonable to me, as it is also allowed to crash.

倒带 2024-11-16 09:24:18
int a[1] = {counter};
q.push(a);

不正确。它调用未定义的行为,因为大括号(for 循环块)之外不存在 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; > as :

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++;
}

这样,您就不必处理原始指针。您不必自己分配或释放内存,我认为这是一种安全的方法!

int a[1] = {counter};
q.push(a);

Not correct. It invokes undefined behvaiour, as a doesn't exist outside the curly braces (the for-loop block). Even if it were well-defined, your code has another problem, all the items in queue is same, as a (the same memory) gets used repeatedly in the loop.

The solution is this:

int *a = new int[1];
a[0] = counter;
q.push(a);

If you do so, then you've to deallocate the memory yourself, of course.


But I'm wondering if every item in queue is just one int,then why not use the following:

queue<int> q;

for (int i = 0; i < 3; i++) 
{
  q.push(counter);
  counter++;
}

Or if you really want array, then why not use std::queue<std::vector<int> > as :

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++;
}

In this way, you don't have to deal with raw pointers. You don't have to allocate or deallocate memory yourself which in my opinion is a safe approach!

泼猴你往哪里跑 2024-11-16 09:24:18

您有未定义的行为,因为您的 a 声明在将其推入队列的循环末尾超出了范围。

可能发生的情况是 a 的内存位置每次都会被重用,但绝对不能保证。下次运行它时,您可能会得到不同的输出,或者您可能会崩溃,或者恶魔可能会从您的鼻孔中飞出。

You have undefined behavior, since your declaration of a goes out of scope at the end of the loop where you're pushing it into the queue.

What's probably happening is that the memory location of a gets reused each time through, but there are absolutely no guarantees. You might get a different output next time you run it, or you might get a crash, or demons may fly out of your nostrils.

半仙 2024-11-16 09:24:18

如果您坚持使用指向整数的指针,下面的代码可以满足您的要求:

#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;
}

If you insist on using pointers to integers, the following code does what you want:

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文