检测并修复C++中的堆损坏
Detecting and fixing heap corruption in C++
我在(win32)C++应用程序中遇到堆损坏问题。在代码中插入_heapch()之后,我设法缩小了原因。应用程序运行;然而,它"不时"崩溃。这是代码:
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] = ' ';
routing_component[j++] = param.regex[i];
}
}
routing_component[j] = ' ';
}
assert(_CrtCheckMemory())非常适合检测内存泄漏。把它放在代码的各个地方,它将帮助你缩小问题的范围。您的应用程序必须使用调试配置生成。此外,它可能会减慢执行速度。
代码可能正在写入regex_d
数组的末尾。在一些地方,有一段代码将i = 1;
赋值,然后在regex_d中执行scanf
。我怀疑它应该从零开始:
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
的原始分配大小。
相关文章:
- 为什么会发生堆损坏
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 平均图像时图像损坏
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 为什么C中的通用链表中存储的数据已损坏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- C++双重释放或损坏(out)
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 使用全局声明的向量时,C++双重释放错误/损坏
- 变量周围的堆栈'...'已损坏
- 运行时检查失败 #2 变量"A"周围的堆栈已损坏
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 删除字符串后C++检测到堆损坏
- 两个垫子的 OpenCV 数据是相同的,但使用 Mat::at 检索时的值已损坏
- 我可以写入关闭的套接字并强制纠正损坏的管道错误吗?
- 损坏的结构字符数组 - sqlite C++
- 运行时检查失败 #2 - 变量"e"周围的堆栈已损坏。发生
- zlib 膨胀在使用小缓冲区时会损坏
- 正在调试 malloc():新内存损坏
- 变量周围的堆栈'sortArray'已损坏