c++ - 检测对已释放的未命名临时文件的访问

标签 c++ constructor reference temporary c++98

如果类 B 有一个构造函数接受对类 A 存储该引用的对象的引用,并使用该类的临时对象调用,该引用似乎在构造函数完成后变为无效(参见 example run )。然而,我尝试过的静态代码分析工具都没有检测到这种情况:

  • g++ -Wall -Wextra -pedantic
  • clang++ -Wall -Wextra -pedantic
  • cppcheck
  • clang-tidy
  • CLion的综合检查

我想我理解编译器的行为符合标准。如何在现有代码库中检测此类代码?哪些编程约定可以帮助避免此类难以发现的错误?

为了完整起见,完整的示例代码和带注释的输出如下。

#include <iostream>

class A {
public:
  explicit A(int i) : i_(i) { std::cerr << this << " A\n"; }
  ~A() { std::cerr << this << " ~A\n"; }

  void do_() const { std::cerr << this << " " << i_ << "\n"; }

private:
  int i_;
};

class B {
public:
  explicit B(const A& a) : a_(a) { std::cerr << this << " B\n"; }
  ~B() { std::cerr << this << " ~B\n"; }
  void do_() const { std::cerr << this << " "; a_.do_(); }

  const A& a_;
};

int main(int, char**) {
  B b(A(42));
  int i = 0;
  b.do_();
  std::cerr << i << " main\n";
}

输出:

# Construction of b
0xffa66138 A
0xffa66134 B
0xffa66138 ~A
# Calling b.do_()
0xffa66134 0xffa66138 42
# Printing i in main()
0 main
# End of main()
0xffa66134 ~B

最佳答案

你可以禁止临时删除的构造函数

class B {
public:
    explicit B(const A& a) : a_(a) { std::cerr << this << " B\n"; }
    B(A&&) = delete;
// ...
};

保证 A 的生命周期长于 B 的方法是采用 shared_ptr

关于c++ - 检测对已释放的未命名临时文件的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42657667/

相关文章:

c++ - 如何创建一个返回对该类对象的引用的静态方法?

C++如何制作像lua一样的表格

c++ - for循环比较二维数组???求助!

c++ - 具有选择排序算法的虚方法函数

c++ - 现代 CMake 应该如何添加 SSE 标志?

java - 为什么在声明子类的对象时会调用父类(super class)的构造函数? ( java )

类中的 C++ fstream

c# - 如何使用内部构造函数从具有新约束的泛型类创建实体

function - 引用类方法

arrays - 在 SQLite 中存储在另一个表中引用的数组