定位问题4--为什么刚创建的对象使用时就没有了?

如下代码

Timer timer = createTimerEng(.....);
operationList.push_back({session, key, timer,0});
printf("insert key %s timer %p callBackData %p",key.c_str(),timer,callBackData);
startTimer(timer);-----------------在timer的库里打印了失败,这明显是刚创建的啊,怎么回事?
背景:
createTimerEng/startTimer 为三方库提供的方法,其它项目使用也没有问题。但是这里startTimer失败,打印了错误日志。
 
现象:
1. 上述代码,在createTimerEng创建的时候,没有错误
2. printf 打印的指针也不是空的
3. 运行startTimer----三方库,此时就报错,但这个库是其它人用的好好的
 
定位:
尝试过多种方法
1. 单独按三方库的指导写了下timer----正常
----初步确认三方库没有问题
2. 分析打印,这里打印的指针地址也没有问题
-------------------------------------------------耗费了较多时间
struct OperationItem {
    std::string a;
    UsbDeviceKey b;
    Timer timer;
    int retryTimes;
    bool operator==(const OperationItem& other) const {
        return session == other.session && key == other.key;
    }
    ~OperationItem() {
      if(timer != nullptr){
    deleteTimer(timer);-------------------------------------拷贝的临时对象析构时,这里针将这个timer delete 掉
    timer = nullptr;
  }
    }
};
3. 单独分析资源释放操作
  ----发现 operationList.push_back({session, key, timer,0}); 这里有一次拷贝构造函数调用,有一个临时对象,在临时对象析构时,会delete timer
 
经验:
1. 从日志分析,不要忽略了潜在的操作----如这里的拷贝复制
2. 对资源的管理,还需慎之又慎
----但过尤不及,探讨语言的新特性来管理这里的资源-----------待研究具体的方法
3. 对资源的使用建立明确的规则,如
  3.1.  明确这里timer的使用和释放,由谁来操作,资源管理集中
  3.2. 有明确的规范来操作此事,如通过类来封装,或使用类似智能指针的方法
 
总结
1. 研究一个更好的自动释放的方法,类封装,或接口封装,或使用语言的特性(auto_ptr等,但需要研究清楚使用场景再使用)
2. 明确规则,资源管理集中
2.1. 如:将timer集中到当前类管理,那么 OperationItem  类就不能有deleteTimer的职责
2.2. 或将 create delete Timer都放到 OperationItem  中管理
2.3. 单独封装资源管理,通过auto_ptr或其它方式,共享,并插入数据结构
 
最终使用了这里的 2.1 ,原因如下
1. 修改最小
2. 好理解
posted @ 2025-11-03 15:50  知易  阅读(6)  评论(0)    收藏  举报