c++ Heap corruption w/ std::vector

Started by
6 comments, last by swiftcoder 9 years, 2 months ago

Thanks for taking the time to read this. I'm using a mesh object that contains std::vectors for vertex and index data.


class Mesh2
{
// snipped for brevity
    std::vector<unsigned short>        indices;

}

void Mesh2::AddFace(unsigned short _i1,unsigned short _i2, unsigned short _i3) {
    
    indices.push_back(_i1);
    indices.push_back(_i2);
    indices.push_back(_i3);

}

The above functions reside in a static lib that contains all rendering code, linked to the main executable. Below are functions in the .Exe.


// In main()

Mesh2 cube;
GenerateCube(&cube,true,true);

and the function GenerateCube


GenerateCube(Mesh2* mesh, bool bGenNorms, bool bGenTangents)

{
 // at some point
 mesh->AddFace(0,1,2);

//.. and so on
}

The issue is as soon as mesh.indices has to resize past 10(it's default size) I get a heap corruption. I'm not sure what must be done to rectify this. If anyone has a good link or can spare 5 minutes for a thorough explanation it would be much appreciated. Everything I've pulled up on google so far has to do with crossing DLL boundaries which I'm not doing, but might be happening behind the scenes in the std::vector. I'm heading back to google for now.

Advertisement
The problem is most likely unrelated to std::vector. Maybe someone is writing beyond array boundaries somewhere (and thereby threshing the memory belong to the std::vector) or maybe you are working with a vector inside an object which has been deleted or went out of scope. The best approach (on MSVC) would be to switch to a Debug build and start it with the debugger. Ideally one of the several additional checks running there will trigger an assert closer to the point where crap actually happens.

The code itself looks correct to me. Very often, heap errors happen at a completely unrelated place and show only much later. Stuff like this is usually hard to debug, but Visual Studio should help you with that.

What is the smallest, simplest program that reproduces the error for you? The code you posted contains no errors, we can't guess at the code you did not post.

Stephen M. Webb
Professional Free Software Developer

BitMaster hit the nail on the head. A typo from my fat fingers:


pUVs[16] = Vector2(  0,  0 ); // Top Quad
pUVs[17] = Vector2(  0,  1 );
pUVs[18] = Vector2(  1,  0 );
pUVs[29] = Vector2(  1,  1 ); // whoops

Thanks all for the suggestions, Bregma, you pointing out that the existing code was fine, led me back to the previous 2 replies. This was in a debug build so i did have access to debugging features but as this was a new situation for me i was not sure what to look for.

HEAP: Free Heap block f6d48 modified at f6d58 after it was freed

The error visual studio 2010 gave me pointed to the location in the heap, but different runs always pointed to different locations. Is there a way i could have found out what line of code allocated what chunk of memory after the fact? Or would i have had to watch each allocation in turn and then use the address given to figure out the offending code? I'm still quite unfamiliar with a lot of the debugging functionality in visual studio

It should be noted that using an std::array<> would probably have caught the error earlier in this case since most implementations will assert in operator[] regarding the validity of the index (without sacrificing speed or space in non-debug builds).

Apart from that, writing beyond the array boundaries is always nasty to debug. If you have your code in some kind of version control system (a good advice in all cases), going back and checking when these errors stop appearing can give clues. Otherwise commenting out bits of code can give clues as well.

Edit: but the best course of action is avoiding situations like this entirely. As above, the std::array<> would have caught the problem, unlike the C style array. If you need a dynamic size, std::vector with the desired size passed to the constructor can work too. If you only access it via operator [] it will assert on bad indices as well and not grow automatically.

The issue is as soon as mesh.indices has to resize past 10(it's default size) I get a heap corruption. I'm not sure what must be done to rectify this. If anyone has a good link or can spare 5 minutes for a thorough explanation it would be much appreciated.
...
The error visual studio 2010 gave me pointed to the location in the heap, but different runs always pointed to different locations. Is there a way i could have found out what line of code allocated what chunk of memory after the fact? Or would i have had to watch each allocation in turn and then use the address given to figure out the offending code?



Assuming Windows, there are some other tools you can use to help track down heap corruption.

If it always happens at a reliable time or a reliable location in memory you can probably use a memory breakpoint to stop when something modifies that block of data.

If it happens under a wider range of situations try using the pageheap flag in Windows' debugging tools.

And if you are on Linux (or as of recently, a Mac), valgrind is a truly magical tool for finding obscure memory errors.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

This topic is closed to new replies.

Advertisement