Segmentation fault when declaring std::vector

Hello,

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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef WORLD_HPP
#define WORLD_HPP

#include <tmx_loader.hpp>
#include <SFML/Graphics.hpp>

const int SCR_WIDTH=1024;
const int SCR_HEIGHT=768;

class World
{
private:
  TMXLoader loader;
  std::vector<std::vector<int>> map;  // Right here
  std::vector<int> meta_layer;
  sf::Image tileset;
  sf::Sprite tile;
  sf::IntRect subRect[160];
  sf::RenderWindow *App;
  int tx;
  int ty;
public:
  bool equalView;
  World(const char *fileName,sf::RenderWindow *dest,int xoff,int yoff);
  void Draw(int x,int y);
  std::vector<int> getMetaLayer() const { return meta_layer; }
};

#endif // world.hpp


When I create an instance of the above object, there is a segmentation fault.

Do you guys have any ideas on why is the OS throwing a segmentation fault?

Thanks in advance and cheers,
Kosmos.
Last edited on
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.
Thanks a lot Catfish,

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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;
	}
      else if(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


I don't know why it is doing that though.

Cheers,
Kosmos.
Last edited on
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.
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?
Athar wrote:

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. 


Thanks to Athar and vlad from moscow.

Cheers,
Kosmos.
Last edited on
Topic archived. No new replies allowed.