2

I'm having an issue with heap corruption in a (win32)C++ application. After inserting _heapchk() into the code I've managed to narrow down the cause. The application runs; however it crashes "every now and then". Here is the code:

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", &regex_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", &regex_d[i]); // <== HEAP CORRUPTION } ... } ... } 

When I attempt to reuse the input_fields vector the heap becomes and remains corrupted throughout the program. param is a container which contains validated user input. The split_regex() method is used to obtain two strings:topology_component and routing_component. Both are of type 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'; } 
1
  • Why not replace (*iter).erase(); (*iter).append(m_res[i]); by *iter = m_res[i]? Should save you from any possible invalidation issues. Commented Aug 30, 2012 at 22:53

2 Answers 2

1

assert(_CrtCheckMemory()) is pretty good for detecting memory leaks. Put it in various places of your code and it will help you to narrow down the issue. Your application must be built with Debug configuration. Also it may slow down an execution.

Sign up to request clarification or add additional context in comments.

Comments

0

The code might be writing past the end of the regex_d array. In a couple places, there is code that assigns i = 1; and then does a scanf into regex_d. I suspect that it should start out out zero:

 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", &regex_d[i]); 

In addition, it seems as if that loop should have a check to verify that it does not increment past the original allocation size of regex_d.

3 Comments

I need to start from 1(I'm creating links between the nodes whose ids are stored in that regex_d array). Using 0 would mean a node creating a link to itself which is not intended
@Sebi: Then possibly the regex_d allocation should be regex_d = new int[n_of_fields+1];
That did the trick. I still wonder why the first part of the parsing did not signal any heap issues.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.