智能指针的延迟报错问题

发布时间:2024年01月04日

最近工作上发现一个比较复杂的代码出现随机报错问题,话不多说,直接debug模式开启ASAN机制构建程序,

set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -O0 -g -fstack-protector -fsanitize=address -fno-omit-frame-pointer")

很快能定位到报错的行,调用某个对象的成员函数的内部报错,说某个成员锁对象有问题,非法读取内存之类的。然后围绕这个锁,看了相关代码,没发现问题。干脆屏蔽这个锁的访问,发现访问某些成员变量也开始报错了,很奇怪,第一感觉是如果对象本身为空,外部调用的时候就应该报错了阿。

实在是想不通,看了一圈代码,也没发现明显问题,难道是ASAN此时报错较晚?干脆做个实验吧。代码如下:

#include <memory>

class Person {
public:
  Person(const std::string& name) : name(name) {
    std::cout << "Construct Person: " << name << std::endl; 
  }
  
  ~Person() {
    std::cout << "Destroy Person: " << name << std::endl;
  }
  void print() {
    printf("xx\n");
    std::cout << "Name: " << name << std::endl; 
  }  
private:
  std::string name;
};

int ptrTest() {
      // 使用make_shared创建shared_ptr实例
  auto p1 = std::make_shared<Person>("John");

  // 直接创建shared_ptr
  std::shared_ptr<Person> p2 = std::make_shared<Person>("Mary");

  // 使用get()获取原始指针
  Person* rawPtr = p1.get();

  // 使用重载的->调用成员函数
  p1->print();

  // shared_ptr支持 copy
  std::shared_ptr<Person> p3;// = p1;
  if(p3) {
      p3->print();
  }
  
  // 当所有shared_ptr都离开作用域或被重置时,对象才会被销毁
  return 0;
}

int main() {
    ptrTest();
return 0;
}

果不其然,p3不赋值的情况下,debug模式下也能进入print内部进行调用,并不报错,如果print内部访问成员变量,那么此时报错,说读取非法内存,asan此时才报错,如果print内部完全不访问任何成员变量,那么整个过程可以顺利进行!即使是Debug模式。

那么最简单的解决方案就是调用智能指针的成员之前,就先检查指针本身是否合法了。直接if判断就行。最根本的解决方法是找到为什么没被赋值,这是必须要解决的问题了。

文章来源:https://blog.csdn.net/haithink/article/details/135381248
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。