资讯详情

【OpenHarmony】make_shared和make_unique失败时总会抛异常,和是否禁用异常无关

一、背景

  • 这种判断在项目代码中有很多:
handler_ = std::make_shared<UsbServerEventHandler>(eventRunner_, pms); if (handler_ == nullptr) { 
             USB_HILOGE(MODULE_USB_SERVICE, "Init failed due to create handler error");     return false; } 
  • 不同的人对此有不同的看法:
    • 有人认为应该判空,防止以后使用handler_的时候对
    • 有人认为,make_shared失败后会抛出异常,而且handler值未定义,

二、探索

1.构建失败场景

思路

  • 目前我们可以肯定的是,new(nothrow),可以申请内存,出错后会返回nullptr
  • 因此可以使用new耗尽内存(包括虚拟内存),然后调用make_shared,这样就可以构建失败的场景。

准备

  • 环境信息
Desktop free                total        used        free      shared  buff/cache   available Mem:         3986712     1072260      119608       38116     2794844     2599996 Swap:        2097148        3148     2094000  ?  Desktop df -lh  Filesystem      Size  Used Avail Use% Mounted on tmpfs           390M  3.4M  386M   1% /run /dev/sda3        98G   13G   80G  14% / tmpfs           2.0G     0  2.0G   0% /dev/shm tmpfs           5.0M  4.0K  5.0M   1% /run/lock /dev/sda2       512M  5.3M  507M   2% /boot/efi tmpfs           390M  104K  390M   1% /run/user/1001  ?  Desktop uname -a Linux ubuntu 5.13.0-20-generic #20-Ubuntu SMP Fri Oct 15 14:21:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux  
  • 所以我们需要耗尽所有的内存。
  • 耗尽后,使用make_shared申请内存,使其出错。
// make_shared.cpp #include <iostream> #include <cstdint> #include <memory>  using namespace std;  struct Memory { 
             uint8_t mem[UINT32_MAX];
};

int main()
{ 
        
    for (uint32_t count = 0; count < UINT32_MAX; ++count) { 
        
        auto byte = new(nothrow) uint8_t[UINT32_MAX];
        if (byte == nullptr) { 
        
            cout << "new failed in loop: " <<  count <<endl;
            break;
        }
    }

    auto shared = make_shared<Memory>();
    cout << "finished!" << endl;
    return 0;
}

2、不同场景下验证

使用异常

  • 编译,不做优化clang++ make_shared.cpp -O0 -o make_shared
  • 运行./make_shared
➜  projects ./make_shared 
new failed in loop: 32766
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
[1]    20796 IOT instruction (core dumped)  ./make_shared

禁用异常

  • 编译,不做优化clang++ make_shared.cpp -O0 -o make_shared -fno-exceptions
  • 运行./make_shared
new failed in loop: 32766
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
[1]    20836 IOT instruction (core dumped)  ./make_shared

三、结论

  • 通过上面的探索我们可以发现,

标签: 104k400vcbb电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台