项目里规则使用了如下数据结构,其中策略模块使用了指针,减少结构体拷贝过程中数据的拷贝,其中refcount引用计数控制结构体生命周期。
struct strategy_rule_st
{
STRATEGY_FUNCTION_TYPE function_type; //功能类型
common_strategy_st *common_strategy; // 策略共同部分数据
int refcount; // 引用计数
union {
port_control_strategy *port_ctrl_strategy; //端口差异策略
#ifdef _MSC_VER
appnet_control_strategy *appnet_ctrl_strategy; //应用管控差异策略
#endif
};
}
void ReleaseStrategyNode(strategy_rule_st* rule) {
if (!rule){
return;
}
if (--rule->refcount == 0){
FWALL_SAFE_DELETE(rule->common_strategy);
}
}
我在下发规则的使用了浅拷贝,只拷贝了指针和引用计数,但是释放的时候调用了真正的析构ReleaseStrategyNode函数,会减引用且可能真正free结构里面的指针。
vector<strategy_rule_st > eaio_rules;
vector<strategy_rule_st > product_rules;
if (StrategyRules[i].common_strategy->product_name == FWALL_WHITE_LIST_NAME) {
eaio_rules.push_back(item);
} else {
product_rules.push_back(item);
}
}
// ....
ReleaseStrategyGroup(&product_rules);
ReleaseStrategyGroup(&eaio_rules);
但是原先的vector里面的结构体还会用到已经被释放的指针。这导致了内存被释放后继续读的隐患,虽然不一定会导致问题,但是可能读到脏数据,导致程序的运行出现奇怪的问题。
修改成如下,直接clear,不调用真正的结构体析构函数,这样只会清理结构体,但不会清理结构体中的指针。
vector<strategy_rule_st > eaio_rules;
vector<strategy_rule_st > product_rules;
if (StrategyRules[i].common_strategy->product_name == FWALL_WHITE_LIST_NAME) {
eaio_rules.push_back(item);
} else {
product_rules.push_back(item);
}
}
// ....
// 浅拷贝vector不用销毁真正策略数据
product_rules.clear();
eaio_rules.clear();
项目里规则使用了如下数据结构,其中策略模块使用了指针,减少结构体拷贝过程中数据的拷贝,其中refcount引用计数控制结构体生命周期。
我在下发规则的使用了浅拷贝,只拷贝了指针和引用计数,但是释放的时候调用了真正的析构ReleaseStrategyNode函数,会减引用且可能真正free结构里面的指针。
但是原先的vector里面的结构体还会用到已经被释放的指针。这导致了内存被释放后继续读的隐患,虽然不一定会导致问题,但是可能读到脏数据,导致程序的运行出现奇怪的问题。
修改成如下,直接clear,不调用真正的结构体析构函数,这样只会清理结构体,但不会清理结构体中的指针。