我在(win32)C ++应用程序中遇到堆损坏问题。将_heapchk()插入代码后,我设法缩小了原因。该应用程序运行;然而它“时不时地”崩溃。这是代码:
void parse_config(void) {
int *regex_d; // regex data parsed fields(from a line from config_file)
vector<string> input_fields; // filtered data
ifstream file(param.topology_file.c_str());// open file for input
ifstream reg_file(param.regex_file.c_str()); // open the regex file and read contents(all content is placed on a single line -- no new line characters allowed)
if(reg_file.is_open())
{
// read regex content into the string regex variable
param.regex.assign((istreambuf_iterator<char>(reg_file)), istreambuf_iterator<char>());
reg_file.close();
}
split_regex();
string buff; // store contents of input file
string::const_iterator start, end;
int temp, temp1, temp2;
int n_of_fields = 0; // number of fields found in an input line
const size_t l = 10; // number of digits each data field has
for(unsigned i = 0; i < strlen(topology_component); i++)
{
if(topology_component[i] == ':')
n_of_fields++;
}
input_fields.resize(n_of_fields);
regex_d = new int[n_of_fields];
for(vector<string>::iterator iter = input_fields.begin(); iter != input_fields.end(); iter++)
{
(*iter).reserve(l);
}
if (file.is_open())
{
file.seekg(0, ios::end);
buff.reserve(file.tellg());
file.seekg(0, ios::beg);
buff.assign((istreambuf_iterator<char>(file)), istreambuf_iterator<char>()); // read contents of file in buff
file.close();
boost::regex expression(topology_component);
boost::match_results<string::const_iterator> m_res;
boost::match_flag_type flags = boost::match_default;
start = buff.begin();
end = buff.end();
// searching the buffer for valid entries
while(boost::regex_search(start, end, m_res, expression, flags))
{
start = m_res[0].second;
flags |= boost::match_prev_avail;
flags |= boost::match_not_bob;
int i = 1;
for(vector<string>::iterator iter = input_fields.begin(); iter != input_fields.end(); iter++, i++)
{
(*iter).erase();
(*iter).append(m_res[i]);
sscanf((*iter).c_str(), "%d", ®ex_d[i]);
}
...
}
n_of_fields = 0;
for(unsigned i = 0; i < strlen(routing_component); i++)
{
if(routing_component[i] == ':')
n_of_fields++;
}
delete[] regex_d;
regex_d = NULL;
input_fields.resize(n_of_fields);
regex_d = new int[n_of_fields];
for(vector<string>::iterator iter = input_fields.begin(); iter != input_fields.end(); iter++) // allocate memory
{
iter->reserve(l);
}
boost::regex expression(routing_component);
boost::match_results<string::const_iterator> m_res;
boost::match_flag_type flags = boost::match_default;
start = buff.begin();
end = buff.end();
// searching the buffer for valid entries
// rtable_cur:0 rtable_dst:0 rtable_nxt:0 rtable_vc:0
while(boost::regex_search(start, end, m_res, expression, flags))
{
start = m_res[0].second;
flags |= boost::match_prev_avail;
flags |= boost::match_not_bob;
// parse one line from config file
int i = 1;
for(vector<string>::iterator iter = input_fields.begin(); iter != input_fields.end(); iter++, i++)
{
(*iter).erase(); // <== HEAP CORRUPTION OCCURS HERE
(*iter).append(m_res[i]); // <== HEAP CORRUPTION
sscanf((*iter).c_str(), "%d", ®ex_d[i]); // <== HEAP CORRUPTION
}
...
}
...
}
当我尝试重用input_fields向量时,堆在整个程序中变为并且仍然被破坏。 param是一个包含经过验证的用户输入的容器。 split_regex()方法用于获取两个字符串:topology_component和routing_component。两者都是char *类型。
void split_regex(void) // regex is of type "topology_component|routing_component"
{
bool split = false;
unsigned i, j = 0;
if(topology_component == NULL)
{
topology_component = (char*)malloc(REGEX_SIZE);
}
if(routing_component == NULL)
{
routing_component = (char*)malloc(REGEX_SIZE);
}
for(i = 0; i < param.regex.size(); i++)
{
if(split == false)
{
if(param.regex.at(i) == '|')
{
split = true;
j = 0;
continue;
}
topology_component[i] = param.regex[i];
}
else
{
topology_component[i-1] = '\0';
routing_component[j++] = param.regex[i];
}
}
routing_component[j] = '\0';
}
答案 0 :(得分:1)
断言(_CrtCheckMemory())非常适合检测内存泄漏。将它放在代码的各个位置,它将帮助您缩小问题范围。您的应用程序必须使用Debug配置构建。它也可能减慢执行速度。
答案 1 :(得分:0)
代码可能正在写regex_d
数组的末尾。在几个地方,有一些代码可以分配i = 1;
,然后将scanf
分配到regex_d中。我怀疑它应该从零开始:
int i = 1; <== should be 0?
for(vector<string>::iterator iter = input_fields.begin(); iter != input_fields.end(); iter++, i++)
{
<snip>
sscanf((*iter).c_str(), "%d", ®ex_d[i]);
此外,似乎该循环应该检查以确认它没有超过regex_d
的原始分配大小。