为什么VS2013在销毁唯一指针时会抛出异常

why does VS2013 throw an exception when destroying unique pointer?

本文关键字:指针 抛出异常 唯一 VS2013 为什么      更新时间:2023-10-16

您能否深入了解此异常的含义以及为什么仅在unique_ptr 是 != nullptr 时才抛出它?

代码编译并运行引发异常。

唯一指针 pFace2 在被销毁时似乎会引发异常。
当它 == nullptr 时,它不会引发异常。

VS2013异常信息为:

在网络.exe 0x00CA6A0C的首次机会例外:0xC0000005: 访问违规写入位置0xCCCCCCD0。

如果存在此异常的处理程序,则程序可能是安全的 继续。

代码是:

 for (auto volume : domain) {
        std::cout << "Volume " << volume->getID() << "n";
        for (auto face : volume->volumeFaces) {
      auto pNeighbourVolume = std::find_if(
          domain.begin(), domain.end(), [&](std::shared_ptr<controlVolume> i) {
            return i->getID() == face.getNeighbour();
          });
      if (pNeighbourVolume != domain.end()) {
        std::cout << "  connected to " << (*pNeighbourVolume)->getID() << "n";
        //This pointer     
        std::unique_ptr<cvVolumeFace> pFace2 = (*pNeighbourVolume)->matchingFace(face); 
        std::cout << "n";
      } //<- here is where code breaks
    }
    std::cout << "nn";
  }

匹配类型的定义是:

std::unique_ptr<cvVolumeFace> controlVolume::matchingFace(cvVolumeFace &neighboursFace) {
  for (auto face : volumeFaces) {
    if ((face.getNeighbour() == neighboursFace.getNeighbour()) &&
        (face.getArea() - neighboursFace.getArea() < face.matchTolerence())) {      
      std::cout << "Matched faces for " << face.getNeighbour() << " and " << neighboursFace.getNeighbour();
      std::unique_ptr<cvVolumeFace> pFace(&face);
      return pFace;
    }
  }
  std::cout << "ERROR: No matching face to return!n";
  return nullptr;
};

中断发生在内存中.h 第 116 行

void _Decref()
    {   // decrement use count
    if (_MT_DECR(_Mtx, _Uses) == 0)  //<-breaks here
        {   // destroy managed resource, decrement weak reference count
        _Destroy();
        _Decwref();
        }
    }
请记住

pFace2if (pNeighbourVolume != domain.end()) { ... }块结束时被销毁,因此它将尝试删除其资源;在这种情况下,该资源似乎是本地对象。

智能指针不是在设计中不考虑对象生存期的借口。 std::unique_ptr是控制另一个对象拥有或有限范围内的对象的生存期的好方法。通常,不应传递此类unique_ptr - 最好仅在该unique_ptr所有者的生命周期内维护所有权,并将原始指针传递给其他用户,这些用户永远不应该尝试获得所有权。另一方面,如果对象的各种访问器的生存期不确定,则可能应考虑std::shared_ptr。这是一个更强大的抽象,支持弱引用等,但它也相当昂贵,因为它涉及一个单独分配的控制块和几个原子引用计数器。