I'm trying to create an XML parser to load Collada files. Currently I'm defining a recursive function which can load each XML node defined as follows:
XMLnode* XMLparser::loadNode(std::vector<std::string> lines, unsigned int level) {
assert(level < lines.size());
std::string line = trim(lines[level]);
// if the line starts with a closing tag (</...) it means that is the closing tag of a
// previous node, therefore, don't create another node
if (line.rfind("</", 0) == 0) {
// before returning, load child nodes.
// recursion condition: process the following file's line, only if it does exist
// (which means that the level must be < of the total number of line of the file)
if (level < lines.size() - 1) {
level++; XMLnode* node = loadNode(lines, level);
}
return nullptr;
}
std::string startingTag = g_startTag(line);
std::vector<std::string> startingTagParts;
// recursion condition: process the following file's line, only if it does exist
// (which means that the level must be < of the total number of line of the file)
if (level < lines.size() - 1) {
level++; XMLnode* node = loadNode(lines, level);
}
return nullptr;
}
where XMLnode
is a custom class - where all functions (including loadNode
) are static
- and trim
is a custom function to remove left and right spaces from a string. The loadNode
function accepts of course a vector of string which contains each line of the XML file. g_startTag
is a function that returns the start tag of the currently processed line (for example if a line starts with <source id="Cube-mesh-colors-Col" name="Col">
, it is returned the content of that starting tag, without the < and > symbols). The issue is that, whenever I try to declare a vector of strings to contain the result of a split operation on the startingTag
string, after a certain amount of lines processed, the program crushes, with the following exception:
Exception not handled at 0x00007FF6CB96597F in "project_name": 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000001D92803FB8).
This is caused, I assume, by the recursion, which continously declares a new vector. Moreover, if I try to call the split
function, it is generated another exception (which I suppose is similar):
Exception not handled at 0x00007FFCC8408739 (ucrtbased.dll) in "project_name": 0xC00000FD: Stack overflow (parametri: 0x0000000000000001, 0x000000C84C2B3FE8).
By the way, the split
function I've defined is the following:
std::vector<std::string> split(std::string str, const char delimiter, bool removePunctuation= false) {
std::vector<std::string> result = {};
// using string streams to split the string
std::istringstream stream(str);
std::string word;
while (std::getline(stream, word, delimiter)) {
// add the new word to the vector of words
if (removePunctuation)
word.erase(std::remove_if(word.begin(), word.end(), ispunct), word.end());
result.push_back(word);
}
return result;
}
The code I used to debug the loadNode function is simply a print statement:
std::cout << "level: " << level << "; starting tag: " << startingTag << std::endl;
and by including the split statement, it is clearly visible that the level reached is lower. When I print the result of splitting,
std::cout << "level: " << level << "; starting tag part 0: " << split(g_startTag(line), ' ')[0] << std::endl;
the same happens: a certain amount of string are correctly processed, then the program crushes.
When I include the split statement I don't explicitly declare a new vector each time in the loadNode
function, but it is declered a temporary holder vector of strings in the split
function.
Is there any way to fix this issue?
Thank you in advance for your help, and excuse my poor English: I'm still practising it!