Game Development Community

Garagegames. Vector is broken.

by Guimo · in Torque Game Engine · 07/19/2008 (6:56 pm) · 5 replies

Hi GarageGames,
I usually dont have any complaint about the engine as I think it provides almost everything I need and, if it doesnt, I usually can implement some resource or code it myself, but this time its a nasty bug which should be solved.

The problem:
Vector wont run any constructor or destructor on the objects which gets inserted or removed from the structure.

Description:
I found the problem when trying to implement my own Grid object to replace the GuiTextListCtrl. I tried to make a Vector of rows where each row included a Vector of StringEntries. The program crashes any time I want to add a new row to the list

Issues:
Memory leaks and failure to properly initialize structures.

Example:
Define the following structure
class Entry
{
public:
  Vector<StringTableEntry> cell;
  U32 id;
  bool active;
  Entry() {
	id = 0; 
	active = true; 
	cell.clear();
  }

};

Then create a vector of these objects like:
Vector<Entry> mList;

Then create an entry and add some strings, then push the row into the vector
Entry e;
e.cell.push_back(StringTable->insert("A");
e.cell.push_back(StringTable->insert("B");
e.cell.push_back(StringTable->insert("C");

mList.push_back(e);

The code crashes in the push_back function:
[code]
template inline void Vector::push_back(const T& x)
{
increment();
mArray[mElementCount - 1] = x; ////Crashes HERE!!!!!!
}
[//code]


Analisys:
The increment function allocates new space for the new element increasing the Vector array but the claimed memory for the new Entry is uninitialized. This causes a nasty problem with the vector of strings inside the Entry structure Vector as a vector relies on its constructor to be run to make sure its correctly initialized. The constructor is never run so tring to execute any operation in the vector (like the assignment) will crash the engine.

This may work fine for vectors of simple structures or datatypes but for complex structures where the structure may need to manage its own memory (like a Vector in this problem) then it will fail.

Requirement:
GG should fix this bug as its part of the core functionality of the engine related to the memory management and not just a "desired" functionality.

Related problems:
After reading the code, I also notice destructors arent run either. This means that it will also cause some problems when removing objects from the Vector if the objects should manage its own memory.

Workaround:
I have enabled STL containers as a workaround this problem.

Thank you very much for your time. I really hope this issue can be solved.

Sincerely,
Guimo

#1
07/19/2008 (7:20 pm)
It's not broken, that's just how Vector is. It's the same with std::vector.

Vector is typically used for data types that require no initialization. For types that do, use a vector of pointers instead.
#2
07/19/2008 (7:38 pm)
Isn't there a big comment in tVector.h to this effect?
#3
07/19/2008 (7:42 pm)
// ============================================================================
/// A dynamic array class. 
///
/// The vector grows as you insert or append
/// elements.  Insertion is fastest at the end of the array.  Resizing
/// of the array can be avoided by pre-allocating space using the
/// reserve() method.
///
/// <b>***WARNING***</b>
///
/// This template does not initialize, construct or destruct any of
/// it's elements.  This means don't use this template for elements
/// (classes) that need these operations.  This template is intended
/// to be used for simple structures that have no constructors or
/// destructors.
///
#4
07/19/2008 (8:12 pm)
@James and Orion,
Never noticed this warning. Just read the code. My mistake.

@Dan
std vectors do invoke constructors and destructors.

So, I apologize then for this request but still think this should be fixed. I guess I will use std containers for this particular problem.

Sincerely,
Guimo
#5
07/21/2008 (5:26 am)
You could always use a VectorPtr object instead and just create/destroy objects as and when you add them or remove them from the container.