Jump to content
  • Advertisement
Sign in to follow this  
AndyEsser

std::vector allocation failure

This topic is 2602 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

Hi All,

I've recently switched from doing std::vector::push_back() to doing std::vector::resize() to avoid having to use it in a loop, and just pre-allocating the number of indices I need.

This has all worked fine recently, however I've just tried it on another std::vector with a custom Class as the std::vector type, and I'm getting problems.

Below is the offending line. If I change it back to a push_back() style then it performs the first allocation, and fails on the second.

Elements is std::vector itself with the type shown below, which contains the svMaterials std::vector.

[source]
struct CHIMERA_MODEL_ELEMENT
{
CHIMERA_MODEL_ELEMENT_HEADER ElementHeader;
std::vector<CHIMERA_MODEL_VERTEX> svVertices;
std::vector<CHIMERA_MODEL_TVERTEX> svTVertices;

std::vector<CHIMERA_MODEL_FACE> svFaces;
std::vector<CHIMERA_MODEL_MATERIAL_DESCRIPTOR> svMaterialsDesc;
std::vector<Chimera::Texture> svMaterials;
};
[/source]


[source]
Elements[elem].svMaterials.resize(Elements[elem].ElementHeader.sNumMaterials);
[/source]

Even if I stick it into a try()...catch().... block it's always fails.

Can anyone see something obvious? I know it's probably a really stupid mistake.

I've been over the previous lines of code to ensure it's not some other memory related issue that's just showing up on this line, but can't see anything.

Many thanks,

Andy

Share this post


Link to post
Share on other sites
Advertisement
Do all the types in CHIMERA_MODEL_ELEMENT and in the vectors implement proper copy operations (copy constructor, copy assignment operator, destructor)?
If not, that can be be your problem.

Share this post


Link to post
Share on other sites
That may well be it - all those of other Vectors (except for svMaterials) are just plain Structs - whereas Chimera::Texture is a class.

Cheers for that. I will go and implement a Copy constructor.

Will let you know if I continue to have problems.

Share this post


Link to post
Share on other sites

That may well be it - all those of other Vectors (except for svMaterials) are just plain Structs - whereas Chimera::Texture is a class.

FYI, there's very little difference between a class and a struct. The only differences are to do with access specifiers.


Cheers for that. I will go and implement a Copy constructor.
[/quote]
The rule of three may be relevant, which is why Wooh mentioned the assignment operator and destructor too.

Incidentally, what kind of failure are you experiencing? Have you debugged the code to ensure the amount of memory being asked for isn't crazy-large?

Share this post


Link to post
Share on other sites
Yep - I was already going to abide by the Rule of Three, but thanks for the link.

The debugger returns this error (on the return line of __tmainCRTStartup within crtexe.c)


First-chance exception at 0x7c90e4ff in Chimera.System.exe: 0xC0000008: An invalid handle was specified.


And it's just a size of 2 that's trying to be 'resized', which equates to 108 bytes.

Share this post


Link to post
Share on other sites
Ok so I've implemented an Assignment Operator and a Copy Constructor (as shown below). I already a destructor for the class. But I'm still continuing to get the same problem.

[source]
Texture::Texture(const Texture& cpTexture)
{
Texture::textureID = 0;
Texture::NeedsUpdate = false;

Texture::hDC = CreateCompatibleDC(0);
}

Texture& Texture::operator=(const Texture& asTexture)
{
Texture::textureID = 0;
NeedsUpdate = false;

hDC = CreateCompatibleDC(0);

return *this;
}
[/source]

Could this have something to do with the fact that this class contains Critical Sections? Given that the error is talking about an invalid handle?

Share this post


Link to post
Share on other sites
Those implementations are almost certainly incorrect. Why are you deleting the mutex in the copy constructor? Your assignment operator is empty.

You probably want your Texture class to be "noncopyable". Sometimes implementing the copy and assignment operators is not only difficult, but is actually a really bad idea for performance. So you instead disable the compiler generated versions of these functions using something like boost::noncopyable or just declaring the functions private and not providing an implementation.

You would then store them in a container of smart pointers, for example using std::shared_ptr.

Share this post


Link to post
Share on other sites
Hi rip-off.

I updated the code sections after I made the post because I'd updated the Copy and Assignment constructors.

I'll try making it non-copyable, and then using std::shared_ptr.

Share this post


Link to post
Share on other sites
Hey, one important element. Resize != reserve.

For efficiency often you want to reserve, then push_back.

By calling resize, you shouldn't call push_back because you would be duplicating your entries. And if you don't, you're calling the constructor for each iteration when calling resize, which if you're later going to overwrite the value, it's a performance hit. Only in a very few cases the compiler may optimize that.

Share this post


Link to post
Share on other sites
Hey - I don't use Resize & push_back at the same time - always only one or the other. I also I've yet to have to Resize multiple times - I tend to just Resize once, at the loading of a Model for the number of materials that the Model requires. After that it should basically never have to be touched again.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!