Jump to content
  • Advertisement
Sign in to follow this  
Prune

WTF error if not vector::reserve()'ed

This topic is 3680 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a simple struct Foo defined nested in a class and the class holds an STL vector<Foo> blah. Since I didn't write a constructor for the struct, I simply do as follows when I call a function AddFoo() to add more Foos to the vector: blah.push_back(Foo()); blah.back().someMember = something; blah.back().anotherMember = somethingElse; ... What happens is that the program crashes unless I initialize with blah.reserve(numFoos) which makes no sense to me since I thought reserve() is just there for efficiency reasons, and push_back() allocates more space when needed... Can someone clear this up for me?

Share this post


Link to post
Share on other sites
Advertisement
Your problem must lay else-where. Most likely, you're accessing past the end of the vector, and the reserve() call is saving you there. Just for the record, this does not crash on my machine:

struct bar
{
struct foo
{
int member;
int someOtherMember;
};

std::vector<foo> vec;

void addFoo()
{
vec.push_back(foo());
vec.back().member = 42;
vec.back().someOtherMember = 9001;
}
};

int main()
{
bar b;
b.addFoo();
}


Edit: Fixed up my test case, I just realized you were doing the addFoo() inside the class.

Share this post


Link to post
Share on other sites
You've corrupted your heap somehow. The push_back causes the vector to go above it's current capacity so it tries to allocate a bigger buffer and crashes because of the aforementioned heap corruption. Calling reserve() hides the problem because you don't need to reallocate.

I'd start looking between the point at which adding reserve() "fixes" the problem and the code you posted.

Share this post


Link to post
Share on other sites
What fails is not push_back(), but when rendering the VBOs of a mesh I store as a member. Rendering the slow way (sending vertex by vertex) has no problem regardless of reserve() use. And rendering of the VBOs works fine if reserve() was used, or where the mesh wasn't in an STL container... I'm really stumped. The function where it fails is

void Mesh::RenderVBO(RT const rt, GLuint att) const
{
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vb);
glVertexPointer(3, GL_FLOAT, 0, 0);

if (rt == NRM || rt == TAN || rt == ALL || rt == ALLTAN)
{
glEnableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, nb);
glNormalPointer(GL_FLOAT, 0, 0);
}

if (rt == TEX || rt == ALL || rt == ALLTAN)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
}

if (rt == TAN || rt == ALLTAN)
{
glEnableVertexAttribArray(att);
glBindBuffer(GL_ARRAY_BUFFER, tanb);
glVertexAttribPointer(att, 4, GL_FLOAT, GL_FALSE, 0, 0);
}

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, fb);
glDrawElements(GL_TRIANGLES, fv.size(), GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(att);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}



vb, nb, tb, tanb, fb, and fv are all member variables of the class. I don't see that this function could possibly fail if the VBOs are correctly created. But I also can't see why they wouldn't be correct, when they work fine in all other cases: when reserve() was used or it's not in an STL container pushed on this way (here I do blah.back().mesh.Open("somefile"); blah.back().mesh.GenVBO(whatever);)

Share this post


Link to post
Share on other sites
The reserve call is definatly keeping you from reallocating memory in your vector<>, so that begs the question. Are your "mesh"es breaking because they are being constructed again, then copied? Maybe you are losing something in the copy when the vector resizes.

Share this post


Link to post
Share on other sites
That was it--I forgot to rebuild VBO's in the copy constructor. I added a check in the copy constructor whether VBO's have been built for the copy-from object, and if so, to generate them for the new.

Thanks man!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!