定位问题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. 好理解

浙公网安备 33010602011771号