the function is supposed to return a pointer to char** where the values will be located as follows in our variable char** temp:
the even indexes in temp(0, 2, 4...) contain the name of the variable parsed. the odd indexes following each variable name contain the value of the variable.
the variable variables=4 should be self explanatory...it specifies how many variables are in the array including itself
the function looks for "=" signs and grabs everything to left of "=" and after a newline character as the variable name and everything to the right of "=" and before a newline character as the variable value. it does this very reilaibly, the problem i am having is with some weird memory corruption. i don't seem to have any problems when parsing a configuration file smaller than 10 variables and values. the problem i get is when i parse files containing more than 10 variables and values. i don't know why but the data seems to not exist outside the main while loop in the parseconfig function. i believe that i may not be allocating memory for the char array properly or some problem of that nature. the weirdest part about the data not existing outside the while loop is that not all the values don't exit, just some of the values at the beginning of the array. it seems as if the first 1/3 of the array of parseconfig becomes corrupted.
******************CODE******************
*********functions used*********
int find(char *str1, char *str2) {
int pos1 = 0;
int pos2 = 0;
return findrecfw(str1, &pos1, str2, &pos2);
}
int find(char *str1, char *str2, int start) {
int pos1 = start;
int pos2 = 0;
return findrecfw(str1, &pos1, str2, &pos2);
}
char *tochar(int num) {
int num_vals = (int)log10(num) + 1;
char *output = (char*)malloc(num_vals + 1);
int number = 0;
int last_number = 0;
for(int i=0; i<=num_vals; i++) {
last_number = number * 10;
number = num / pow(10, num_vals - i - 1);
output[i] = static_cast<char>(number - last_number + 48);
}
output[num_vals] = '\0';
return output;
}
*********PROBLEMATIC FUNCTION*********
char **parseconfig(char *path) {
ifstream file;
//store length of file in len
file.open(path);
int len = 0;
while(file.get() != EOF) {
len++;
}
file.close();
//store contents of file in load for parsing into user
file.open(path);
char *load = (char*)malloc(len + 1);
char temp;
int position = 0;
int num_vars = 0;
while((temp = static_cast<char>(file.get())) != EOF) {
load[position] = temp;
position++;
}
load[len] = '\0';
file.close();
//calculate number of variables to be parsed
int var_loc = 0;
while((var_loc = find(load, "=", var_loc + 1)) != -1) {
num_vars++;
}
//start parsing file
char *line;
char **vars;
vars = (char**)malloc(num_vars * 2 + 2);
int vars_pos = 0;
int vars_processed = 0;
int current = 0;
int load_len = strlen(load);
int templen = 0;
vars[vars_pos] = (char*)malloc(10);
vars[vars_pos] = "variables";
vars_pos++;
vars[vars_pos] = (char*)malloc(strlen(tochar(num_vars)) + 1);
vars[vars_pos] = tochar(num_vars + 1);
vars_pos++;
while(vars_processed < num_vars) {//*****CORRUPTION OCCURS IN THIS LOOP
//get variable name
current = find(load, "=", current + 1);
vars[vars_pos] = (char*)malloc(strlen(get(load, findbw(load, "\n", current) + 1, current)) + 1);
vars[vars_pos] = get(load, findbw(load, "\n", current) + 1, current);
vars_pos++;
//get variable value
if((find(load, "\n", current)) == -1) {
vars[vars_pos] = (char*)malloc(strlen(load) - 1 - current);
vars[vars_pos] = get(load, current + 1, strlen(load));
}
else {
vars[vars_pos] = (char*)malloc(strlen(get(load, current + 1, find(load, "\n", current) - 1)) + 1);
vars[vars_pos] = get(load, current + 1, find(load, "\n", current));
}
vars_pos++;
vars_processed++;
}
return vars;
}
******************END CODE******************
the parseconfig function does not print these results....i did that in my main function...the main function does not contribute to the corruption problem. all it does it call the parseconfig function store the returned data and print it
for this sample config file i filled it with test=test 100 times and this is what i get
******************MY RESULTS******************
temp[0]: variables
temp[1]:
temp[2]: `
temp[3]: ?
temp[4]: ?
temp[5]:
temp[6]: `
temp[7]: ?
emp[8]: ?
temp[9]:
temp[10]: `"
temp[11]: ?$
temp[12]: ?&
temp[13]: test
temp[14]: test
temp[15]: test
temp[16]: test
temp[17]: test
temp[18]: test
temp[19]: test
temp[20]: test
temp[21]: test
temp[22]: test
temp[23]: test
temp[24]: test
temp[25]: test
temp[26]: test
temp[27]: test
temp[28]: test
temp[29]: test
temp[30]: test
temp[31]: test
temp[32]: test
temp[33]: test
temp[34]: test
temp[35]: test
temp[36]: test
temp[37]: test
temp[38]: test
temp[39]: test
temp[40]: test
temp[41]: test
temp[42]: test
temp[43]: test
temp[44]: test
temp[45]: test
temp[46]: test
temp[47]: test
temp[48]: test
temp[49]: test
temp[50]: test
temp[51]: test
temp[52]: test
temp[53]: test
temp[54]: test
temp[55]: test
temp[56]: test
temp[57]: test
temp[58]: test
temp[59]: test
temp[60]: test
temp[61]: test
temp[62]: test
temp[63]: test
temp[64]: test
temp[65]: test
temp[66]: test
temp[67]: test
temp[68]: test
temp[69]: test
temp[70]: test
temp[71]: test
temp[72]: test
temp[73]: test
temp[74]: test
temp[75]: test
temp[76]: test
temp[77]: test
temp[78]: test
temp[79]: test
temp[80]: test
temp[81]: test
temp[82]: test
temp[83]: test
temp[84]: test
temp[85]: test
temp[86]: test
temp[87]: test
temp[88]: test
temp[89]: test
temp[90]: test
temp[91]: test
temp[92]: test
temp[93]: test
temp[94]: test
temp[95]: test
temp[96]: test
temp[97]: test
temp[98]: test
temp[99]: test
******************END RESULTS******************
Hmmmm... This is really not a good way to write a file loader/parser. You will no doubt end up with memory issues (as is already happening).
Your code is C, not C++ btw. You have used mostly C conventions.
I would consider loading the entire file into either a hashmap (if any variable name must be unique, or over-write previous declarations) or a vector (as a std::string) and then parse it from there.
Some issues I can see already:
1 2 3 4 5 6 7
//store length of file in len
file.open(path);
int len = 0;
while(file.get() != EOF) {
len++;
}
file.close();
file.get() will only return 1 character. Not 1 line, you are merely counting the number of characters on the first line and using this in your malloc() statement.
You have not included your memory freeing code. Are you freeing the memory you have allocated?
This is some simple C++ code to load an entire file into a vector. And has no memory allocation of de-allocation to worry about.
1 2 3 4 5 6 7 8 9 10 11 12 13
vector<string> vFileLines;
ifstream fConfig(FileName.c_str());
if (!fConfig)
throw string("Failed to open file: " + FileName);
string sLine = "";
while (getline(fConfig, sLine)) {
if (sLine.length() == 0)
continue;
vFileLines.push_back(sLine);
}
Thank you very much for the advice. I have solved my original problem that was the reason that I made this post. However, I noticed new problems like memory leaks. I will definitely take note of your advice and look deeper into better c++ programming practices.
There is only one part of the code you posted that I can't figure out. Could you possibly explain the role of "ifstream fConfig(FileName.c_str());" in the code you posted?
ifstream fConfig(FileName.c_str());
it creates an ifstream (input file stream, to import some data) named fConfig. And the path-name for the file is the FileName.c_str() . FileName is a string but the fstream takes only c-type strings. That's why the necessary ".c_str()" that converts from c++ object string to c-type string.