当前位置: 首页 > 知识库问答 >
问题:

C使用基于范围的指针循环和向量时的错误[重复]

东门翰
2023-03-14

在处理指针向量时,我偶然发现了一个奇怪的bug:

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);
      |     ^

(ARCH上的GCC 9.2.0也复制了这个Bug,但Apple clang 11.0.0给出了预期的输出)

预期产出:

$ ./mwe
42

实际产量:

$ ./mwe 
1533476528
$ ./mwe
-1607700816
$ ./mwe
<insert random huge number here>

我是否无意中在某处引入了未定义行为?如果没有,为什么这没有按预期工作?

共有1个答案

王季萌
2023-03-14

for(A el: vec)意味着您在迭代时正在创建vec中每个元素的副本。

您要将用于(A

 类似资料:
  • 由于valgrind中出现了一些分段错误和警告,我发现这段代码不正确,并且在for range循环中有一些悬而未决的引用。 看起来好像开始和结束是从一个临时循环中提取的,并且在循环中丢失了。 当然,一种方法是 然而,我想知道为什么for(auto e:f()[5])是一个错误,以及是否有更好的方法或某种方法来设计f,甚至容器(

  • C 11 使用基于范围的for循环对作为类成员的std::向量进行迭代的代码是什么?我尝试了以下几个版本:

  • 在std::unordered_映射上运行基于范围的for循环时,循环变量的类型似乎不使用引用类型: MSVC 2017、gcc 8.2和clang 7.0.0都在这里报告了一个失败的断言。与std::vector相反,它的断言不会失败,正如人们所期望的那样: 然而,在MSVC 2017和gcc 8.2上,修改局部变量r的循环将产生明显的副作用: 例如,此程序将打印(忽略订单): 我遗漏了什么?尽

  • 在临时范围上基于范围的for循环中,Barry提到以下内容不受被破坏的临时对象的影响,我测试的成员v确实存在于for循环的整个循环中(因为在for循环的整个循环中没有调用析构函数X)。解释是什么?

  • 问题内容: 请检查以下代码段: 链接到这里:https : //play.golang.org/p/cdryPmyWt5 上面的代码将检查for循环中的指针和值之间的差异,而go语句也同时使用。对于代码: 我们知道,控制台将打印 三三三 的结果,因为循环运行到其最终的够程开始执行,其中写V作为片的最后一个元素之前。但是指针呢? 好像打印 一二三 ,为什么呢? 谢谢。 问题答案: 答:在调用函数之前

  • 我在实验基于范围的for循环时发现,如果你使用基于范围的for循环来循环一个向量,它会出现超出范围的错误,如果你使用基于范围的for循环,有没有办法避免这个错误 它会显示此错误