STL Vector problem (Segmentation Fault)

Hi everyone, I'm writing a game. There's a sprite class which contains vector of animation class. The problem is when I load the animation from files and assign to the vector, the first few animations are loaded well (actually 2) but at the third animation class, the program crashes and give segmentation fault. Here is a condensed version of the code.
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
class sprite : public gameobject
{
    private:
    vector<animation> anim;
    
    public:
    
    sprite() {animationcount = 0; anim.resize(MAXANIM);}
    
   

};

//The problem happens in this portion

void sprite::ReadEveryThing(void *parserex)
{
  char *element,*nextanim;
  char animationdata[1000];
  
  int i=0;
  char *Buffer = new char[1000];  //when I declared it as char Buffer[1000], //Problem occured at i =0

  myxmlparser *parser = (myxmlparser*)parserex;
  animation loadedanim;


  parser->GetElementData (parser->gfile,"bitmapPath",bmpname);
  parser->GetElementData(parser->gfile,"animations",Buffer);

  //element will hold the buffer data temporarily
  nextanim = Buffer;
  while ((element = parser->GetNextElement(nextanim)) != NULL)
    {
      //Now element used as pointer to next Animation
      element = parser->GetElementData(nextanim,element,animationdata);
      
     loadedanim.addanimationframe(animationdata,parserex);

      anim[i] = loadedanim;  //The problem occurs here at i=2
      i++;
      nextanim = element;
    }
    delete Buffer;

}

//Please note that this is not complete code. I've condensed it as much as
//possible.



I am fairly new to STL vector (In fact in C++). And I've been working at this
the whole day. Man I'm real cooked up. Any help will be appreciated.
Thanks in advance
If MAXANIM is large enough there should be no problems with your use of vector. Though you're not really using the vector properties of the vector... You could remove that resize and change line 40 to anim.push_back(loadedanim);

To debug, add some output to the loop. Print the values of strings involved and size of anim, if you don't change it like I said.

Declaring char Buffer[1000] shouldn't cause problems either..
@hamsterman:
Thanks for the feedback but I've tried everything you said already. But it doesn't work! And yes, I've also used the vector properties like you said but that doesn't work too.
And by the way,

The MAXANIM is defined as 5, but the program crashes at i = 2.

And I managed to save a stack trace too but I couldn't understand it (I'm new you know). Hope you guys will find it useful


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
#0 00416DC5	__gnu_cxx::__normal_iterator<animation*, std::vector<animation, std::allocator<animation> > >::__normal_iterator(this=<incomplete type>, __i=<incomplete type>) (D:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_iterator.h:603)
#1 0043D688	std::vector<animation, std::allocator<animation> >::begin(this=0x6365536d) (D:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_vector.h:314)
#2 0043D9D9	std::vector<animation, std::allocator<animation> >::operator[](this=0x6365536d, __n=2) (D:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_vector.h:462)
#3 0040238B	sprite::ReadEveryThing(this=0x63655265, parserex=0x90d3e74) (D:/Program Files/CodeBlocks/C++ Projects/Game-Test/gamedata.cpp:90)
#4 00000000	0x6372756f in ??() (??:??)
#5 00000000	0x63655265 in ??() (??:??)
#6 00000000	0x090d3e74 in ??() (??:??)
#7 00000000	0x09090909 in ??() (??:??)
#8 00000000	0x643c0909 in ??() (??:??)
#9 00000000	0x74617275 in ??() (??:??)
#10 00000000	0x3e6e6f69 in ??() (??:??)
#11 00000000	0x3c343332 in ??() (??:??)
#12 00000000	0x7275642f in ??() (??:??)
#13 00000000	0x6f697461 in ??() (??:??)
#14 00000000	0x090d3e6e in ??() (??:??)
#15 00000000	0x09090909 in ??() (??:??)
#16 00000000	0x6f3c0909 in ??() (??:??)
#17 00000000	0x65736666 in ??() (??:??)
#18 00000000	0x6f703e74 in ??() (??:??)
#19 00000000	0x28746e69 in ??() (??:??)
#20 00000000	0x30202c30 in ??() (??:??)
#21 00000000	0x6f2f3c29 in ??() (??:??)
#22 00000000	0x65736666 in ??() (??:??)
#23 00000000	0x090d3e74 in ??() (??:??)
#24 00000000	0x09090909 in ??() (??:??)
#25 00000000	0x662f3c09 in ??() (??:??)
#26 00000000	0x656d6172 in ??() (??:??)
#27 00000000	0x090d3e37 in ??() (??:??)
#28 00000000	0x09090909 in ??() (??:??)
#29 00000000	0x72663c09 in ??() (??:??)
Last edited on

You have to debug ReadEveryThing(). Its crashing while you are trying to access some index of vector std::vector<animation>

try to step inside the function and debug it.

If you find it difficult, use some graphical debugger.
I am using GNU GDB and yes I already stepped in there, that's why I was able to write this
1
2
3
4
5
     loadedanim.addanimationframe(animationdata,parserex);

      anim[i] = loadedanim;  //The problem occurs here at i=2
      i++;
      nextanim = element;


And one thing I found out was after the call to GetElementData function the third time(at i = 2)
the anim pointer in watch window is altered. I don't know what is causing this but it changes and points to corrupt location. Here is the code of GetElementData function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 char* myxmlparser::GetElementData(char* file, const char* element,char *Buffer )
        {
            char node[MAXNAME];
            char fparserdata[1000];
            char* first, *second;
            int nodelength = 0;
            sprintf (node,"<%s>",element);
            nodelength = strlen(node);
            first = strstr(file,node);

            sprintf (node,"</%s>",element);
            second = strstr(first,node);
            if (first == NULL || second == NULL)
            {
                Buffer = NULL;
                return NULL;
            }
            memcpy (Buffer,first+nodelength,int(second-first)-nodelength);
            return second+nodelength+1;
        }


Though once I felt that the problem may exist at the call to RtlAllocateHeap API!!
The problem still persists please help.
First, you should update your build environment. GCC 3.4.5 is ancient and the debugger seems to be buggy.
Get rid of MinGW (Code::Blocks too if it is outdated) and install the package including MinGW here:
http://www.codeblocks.org/downloads/26

Second, you should define the global macro _GLIBCXX_DEBUG in the debug build.
This will alert you of any out-of-bounds accesses in standard containers and dereferencing of invalid iterators.

There's also an error in line 44: It should be delete[] Buffer;. Pointers returned by new[] must always be deleted with delete[].

Another project you have before you is to banish all uses of C strings from your program. Messing with these is a common source of errors, especially if you're not experienced yet.

And what is the meaning of this cast in line 24?
myxmlparser *parser = (myxmlparser*)parserex;
Why isn't the parameter a myxmlparser pointer in the first place?
If you absolutely need to cast from void* (which is rare), you should use reinterpret_cast.
First, you should update your build environment. GCC 3.4.5 is ancient and the debugger seems to be buggy.
Get rid of MinGW (Code::Blocks too if it is outdated) and install the package including MinGW here:
http://www.codeblocks.org/downloads/26


I'm on it.


Second, you should define the global macro _GLIBCXX_DEBUG in the debug build.
This will alert you of any out-of-bounds accesses in standard containers and dereferencing of invalid iterators.


Sure thing



There's also an error in line 44: It should be delete[] Buffer;. Pointers returned by new[] must always be deleted with delete[].



Thanks for the tip



Another project you have before you is to banish all uses of C strings from your program. Messing with these is a common source of errors, especially if you're not experienced yet.

What are C strings? I didn't get this one.



And what is the meaning of this cast in line 24?
myxmlparser *parser = (myxmlparser*)parserex;
Why isn't the parameter a myxmlparser pointer in the first place?
If you absolutely need to cast from void* (which is rare), you should use reinterpret_cast.
ico


Phew! you know I had to do that because the compiler won't allow me to. When I used myxmlparser then it said not defined .Maybe it didn't encountered the myxmlparser.h file, that's what I thought. So I included myxmlparser.h first but then it said not defined the animation class (I used animation class in myxmlparser too) This has caused me a whole lot of problems. If you can suggest something.

how is anim[i] defined? is it a vector?

If that's the case, you should use push_back on vector rather than doing this. This will surely crash. In fact this should crash on the first iteration only, I am surprised why it ain't crashing and going till 2.
@OP. C string is any kind of char array. It might be better to use std::string instead.
It's hard to say what was the problem with your includes without knowing what exactly included what, but you might find http://www.cplusplus.com/forum/articles/10627/ useful.

@writetonsharma. anim is a member of the sprite class and it was resized in constructor. Did you read the thread?

@hamsterman, aaaah.. i just read the function and didn't see the constructor and that's why I was wondering how it's going till index 2. Dont know how I missed that.
In that case my suggestion goes void.
I removed old MingW and got new. And here's what I found
In "new_allocator.h"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 const_pointer
      address(const_reference __x) const { return &__x; }

      // NB: __n is permitted to be 0.  The C++ standard says nothing
      // about what the return value is when __n == 0.
      pointer
      allocate(size_type __n, const void* = 0)
      { 
	if (__builtin_expect(__n > this->max_size(), false))     //THe Error is here
	  std::__throw_bad_alloc();                                        //And this is throwing the segmentation fault

	return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));   //This also caused problem when I used push_back method instead of [] operator. Any suggestions
      }

      // __p is not permitted to be a null pointer.
      void
      deallocate(pointer __p, size_type)
      { ::operator delete(__p); }


But I don't have any ideas as to what does this means.

And here is the stack trace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#0 00000000	__gnu_cxx::new_allocator<animationframe>::allocate(this=0x3e4b68, __n=4037943823) (d:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/ext/new_allocator.h:86)
#1 0044E52A	std::_Vector_base<animationframe, std::allocator<animationframe> >::_M_allocate(this=0x3e4b68, __n=4037943823) (d:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_vector.h:140)

#2 0044E640	_Vector_base(this=0x3e4b68, __n=4037943823, __a=@0x22d124) (d:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_vector.h:113)

#3 004655A3	vector(this=0x3e4b68, __x=@0x22d124) (d:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_vector.h:242)

#4 0041F471	animation(this=0x3e4a60) (D:/Program Files/CodeBlocks/C++ Projects/Game-Test/gamedata.h:34)

#5 0041DAA9	__gnu_cxx::new_allocator<animation>::construct(this=0x22fd1c, __p=0x3e4a60, __val=@0x22d01c) (d:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/ext/new_allocator.h:105)

#6 0046613E	std::vector<animation, std::allocator<animation> >::push_back(this=0x22fd1c, __x=@0x22d01c) (d:/program files/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_vector.h:737)

#7 00401F98	sprite::ReadEveryThing(this=0x22fc14, parserex=0x22d284) (D:\Program Files\CodeBlocks\C++ Projects\Game-Test\gamedata.cpp:92)

#8 00401D29	sprite::LoadFromFile(this=0x22fc14, fname=0x472026 "Untitled.xml") (D:\Program Files\CodeBlocks\C++ Projects\Game-Test\gamedata.cpp:59)

#9 00401389	main(argc=1, argv=0x3e3cf0) (D:\Program Files\CodeBlocks\C++ Projects\Game-Test\mainex.cpp:7)
Last edited on
Topic archived. No new replies allowed.