views:

873

answers:

5

I've run into a really strange bug, that I'm hoping someone can explain. I have a simple std::vector<V3x>, where V3x is a 3d vector (the linear algebra kind.) The following code causes a std::length_error exception to be thrown:

std::vector<V3x> vertices;
int vertexCount = computeVertexCount();
vertices.resize(vertexCount); // throws std::length_error

I've verified that computeVertexCount() returns a value of 35, which is far far below vector::max_size() so there's no way it's asking for too much memory.

I traced the exception down into the definition of std::vector, to the following two functions.

void resize(size_type _Newsize, _Ty _Val)
 { // determine new length, padding with _Val elements as needed
 if (size() < _Newsize)
  // NOTE: here, _Newsize - size() = 35
  _Insert_n(end(), _Newsize - size(), _Val); 
 else if (_Newsize < size())
  erase(begin() + _Newsize, end());
 }

void _Insert_n(const_iterator _Where,
 size_type _Count, const _Ty& _Val)
 { // insert _Count * _Val at _Where
  // NOTE: here, _Count = 3435973836
  ...
 }

So when the _Count parameter is passed between resize() and _Insert_n(), the value changes from 35 to 3435973836. I'm assuming the memory has somehow become corrupted, but I have no idea how that could be.

For a little more context in case it's part of the problem, this code sits in a .dll plugin that I'm loading from Softimage XSI.

Does anyone know what might cause something like this to happen?

EDIT: SOLUTION

nobugz, I could kiss you.

The size of std::vector was changing inside my .dll, because of _HAS_ITERATOR_DEBUGGING in VS2008. The search led me to someone with the same problem, and it was fixed by adding the following at the top of my project:

// fix stack corruption errors caused by VS2008
#define _HAS_ITERATOR_DEBUGGING 0
#define _SECURE_SCL 0
A: 

posted code is correct and you can assume that std::vector has no bugs. replicate the exception in the purest possible environment (new blank project). could it be something dumb like this in ComputeVertexCount()?

Dustin Getz
A: 

I suggest reviewing the C++ options configured for the projects involved. Ensure that they all share the same alignment and run-time settings. Are you building the .DLL involved?

Henk
+2  A: 

Whenever a parameter or local variable changes unexpectedly, there's a good chance it's due to stack corruption. This can occur whenever you use an uninitialized local variable or store data beyond the memory allocated to a local string or array.

A simple way to debug this:

  1. Load your program into a debugger.
  2. Insert a breakpoint at the first line of code in the offending function.
  3. Execute the program until it hits the breakpoint.
  4. Set a watch on the variable that changes unexpectedly.
  5. Step through the function until the unexpected change occurs.

The change will occur when the un-allocated (or mis-allocated) memory is written. The target of the write is the offending variable.

Adam Liss
+12  A: 

The value 3435973836 is significant. In hex, that's 0xcccccccc. That's the value assigned to local variables in Debug mode by the stack frame initialization code. When you see it back while debugging, you'd say "ah, variable not initialized". Maybe that gets you a bit closer to solving this.

You mention DLL. That's relevant too. Iterator debugging might get you into trouble, you cannot mix code that has it turned off with code that doesn't. Since the DLL is probably compiled without it, try #define _HAS_ITERATOR_DEBUGGING 0.

Hans Passant
+1: Thanks for some very helpful info!
Adam Liss
Always look at the hex representation of unexpected very large values. They frequently tell you you've gone off into never land, like this one.
Rob K