Skip to content

浅拷贝后真析构引发的读错数据问题 #29

Description

@bingtaoli

项目里规则使用了如下数据结构,其中策略模块使用了指针,减少结构体拷贝过程中数据的拷贝,其中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();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions