When I run my program, I get a segmentation fault. This is what the gdb debugger outputs:
1 2 3 4 5
Program received signal SIGSEGV, Segmentation fault.
0x0804d048 in std::vector<int, std::allocator<int> >::emplace_back<int>(int&&)
(this=0x0) at /usr/include/c++/4.6/bits/vector.tcc:95
95 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
I believe this is what is causing the segmentation fault:
A segmentation fault happens when you try to access memory you aren't allowed to. In your case, this may happen if you try to read/write outside the vector.
Hint: vector::at(), unlike vector::operator[], will at least throw an exception with a slightly better error message, when you're going out of range.
As for your posted code, it looks fine to me. I suggest you post the functions too.
I changed all vector::operator[] to vector::at(), and the program threw an exception, here is the function that does it, I localized the line that throws the exception, the line is marked with a comment:
std::vector<std::vector<int>> TMXLoader::Parse()
{
std::vector<std::vector<int>> output;
std::string line;
std::vector<std::string> tmp;
int yt=1;
int pos=0;
int l_pos=0;
int tilewidth=0;
int tileheight=0;
int tw_pos;
int tw_pos_end;
int th_pos;
int th_pos_end;
int layer_i=0;
while(getline(map,line))
{
if(line.find("<map")!=std::string::npos)
{
tw_pos=line.find("width=\"");
tw_pos+=std::string("width=\"").size();
for(tw_pos_end=tw_pos;line[tw_pos_end]!='"';++tw_pos_end);
tilewidth=atoi(line.substr(tw_pos,tw_pos_end-tw_pos).c_str());
map_width=tilewidth;
th_pos=line.find("height=\"");
th_pos+=std::string("height=\"").size();
for(th_pos_end=th_pos;line[th_pos_end]!='"';++th_pos_end);
tileheight=atoi(line.substr(th_pos,th_pos_end-th_pos).c_str());
map_height=tileheight;
}
elseif(line.find("<data encoding=\"csv\">")!=std::string::npos)
{
while(yt<=tileheight)
{
getline(map,line);
tmp=split(line,',');
for(int i=0;i<tilewidth;++i)
{
output.at(layer_i).push_back(atoi(tmp[i].c_str())); // This is what is throwing the exception
}
yt++;
}
layer_i++;
}
}
return output;
}
Here is the exception in more detail:
1 2 3
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
It's doing that because you're trying to access an element that doesn't exist.
Since output is empty and you never add any elements, that's not particularly surprising.
It's doing that because you're trying to access an element that doesn't exist.
Since output is empty and you never add any elements, that's not particularly surprising.
vlad from moscow wrote:
Vector output is empty but you are trying to use method at().
output.at(layer_i).push_back(atoi(tmp[i].c_str())); // This is what is throwing the exception
What are you awaiting has to be?
I thought that doing output.at(1), would create an element. I was wrong; it also makes no sense.
I fixed the code, perhaps it will be of particular use to future readers:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
for(int i=0;i<tilewidth;++i)
{
/* Because the the line below us is trying to access an element of the array that has not been
created yet, there is an exception, 'output' is of type std::vector<std::vector<int>>, I
changed it's type to std::vector<int>, and rewrote that line as:
output.push_back(atoi(tmp[i].c_str())); */
output.at(layer_i).push_back(atoi(tmp[i].c_str())); // This is what is throwing the exception
}
yt++;
}
/* The 'layer_i' variable was removed, and a std::vector<std::vector<int>> object was created, called
'f_output'. I rewrite this line as:
f_output.push_back(output); */
layer_i++; // This variable was removed
}
}
// Note: Of course I return f_output instead of output.