Closed xezon closed 2 months ago
Ah it does access m_vector
. Ok.
template<typename T> T &VectorClass<T>::operator[](int index)
{
captainslog_assert(unsigned(index) < unsigned(m_vectorMax));
return m_vector[index];
}
Ok looks like m_vector contains garbage to begin with
Name | Value | Type | |
---|---|---|---|
◢ | m_lod->m_vector,0x10 | 0x052b818c {{m_model=0x004f3e20 {w3dview.exe!void(* DX8RigidFVFCategoryContainer::`vftable'[8])()} {...} ...}, ...} | HLodClass::ModelNodeClass[0x00000010] |
◢ [0x00000000] | {m_model=0x004f3e20 {w3dview.exe!void(* DX8RigidFVFCategoryContainer::`vftable'[8])()} {m_bits=0x0046c730 ...} ...} | HLodClass::ModelNodeClass | |
◢ m_model | 0x004f3e20 {w3dview.exe!void(* DX8RigidFVFCategoryContainer::`vftable'[8])()} {m_bits=0x0046c730 m_transform=...} | RenderObjClass * | |
▶ RefCountClass | {m_numRefs=0x0046b700 } | RefCountClass | |
▶ PersistClass | {...} | PersistClass | |
◢ MultiListObjectClass | {m_listNode=0x004695d0 {w3dview.exe!DX8RigidFVFCategoryContainer::Add_Delayed_Visible_Material_Pass(MaterialPassClass , MeshClass )} {...} } | MultiListObjectClass | |
◢ __vfptr | 0x0046a630 {w3dview.exe!DX8RigidFVFCategoryContainer::Check_If_Mesh_Fits(MeshModelClass *)} {0x8bec8b55} | void | |
[0x00000000] | 0x8bec8b55 | void * | |
▶ m_listNode | 0x004695d0 {w3dview.exe!DX8RigidFVFCategoryContainer::Add_Delayed_Visible_Material_Pass(MaterialPassClass , MeshClass )} {...} | MultiListNodeClass * | |
m_bits | 0x0046c730 | unsigned long | |
▶ m_transform | {Row=0x004f3e3c {{X=7.362e-39#DEN Y=6.482e-39#DEN Z=6.494e-39#DEN ...}, {X=6.492e-39#DEN Y=6.488e-39#DEN ...}, ...} } | Matrix3D | |
m_objectScale | 6.482e-39#DEN | float | |
m_houseColor | 0x00502b90 | unsigned int | |
▶ m_cachedBoundingSphere | {Center={X=6.481e-39#DEN Y=0.00000000 Z=3.37500000 } Radius=7.363e-39#DEN } | SphereClass | |
▶ m_cachedBoundingBox | {m_center={X=6.524e-39#DEN Y=6.507e-39#DEN Z=7.363e-39#DEN } m_extent={X=6.524e-39#DEN Y=6.507e-39#DEN ...} } | AABoxClass | |
m_nativeScreenSize | 6.506e-39#DEN | float | |
m_isTransformIdentity | true (0xb0) | bool | |
▶ m_scene | 0x00470410 {w3dview.exe!VectorClass<FontCharsBuffer >::Resize(int, FontCharsBuffer const *)} {m_ambientLight=...} | SceneClass * | |
▶ m_container | 0x0046eba0 {w3dview.exe!VectorClass<FontCharsBuffer *>::Clear(void)} {m_bits=0x0446c704 m_transform=...} | RenderObjClass * | |
m_userData | 0x0046fba0 {w3dview.exe!VectorClass<FontCharsBuffer >::ID(FontCharsBuffer const &)} | void * | |
▶ m_unknown | 0x0046fbf0 {w3dview.exe!VectorClass<FontCharsBuffer >::ID(FontCharsBuffer const *)} {...} | RenderObjUnk * | |
m_boneIndex | 0x01427790 | int |
I wonder if something is missing in this constructor:
template<typename T>
VectorClass<T>::VectorClass(int size, const T *array) :
m_vector(nullptr), m_vectorMax(size), m_isValid(true), m_isAllocated(false)
{
// Allocate the vector. The default constructor will be called for every
// object in this vector.
if (size > 0) {
if (array != nullptr) {
m_vector = new ((void *)array) T[size];
} else {
m_vector = new T[size];
m_isAllocated = true;
}
}
}
It allocates m_vector, but leaves it in unitialized state. It does not copy array.
If I understand this correctly it will use "array" as buffer to construct on. And that array cannot be deallocated as long as that VectorClass is used. So if we lose "array", then hell breaks lose.
There appear to be no callers for the placement new code paths (2). That is good.
So the VectorClass element is
class ModelNodeClass
{
public:
RenderObjClass *m_model;
int m_boneIndex;
bool operator==(const ModelNodeClass &src) { return m_model == src.m_model && m_boneIndex == src.m_boneIndex; }
bool operator!=(const ModelNodeClass &src) { return m_model != src.m_model || m_boneIndex != src.m_boneIndex; }
};
It has no constructor. So this will construct with garbage pointers.
m_lod[1] to m_lod[6] look garbage.
Is this perhaps meant to access
m_lod->m_vector
instead?Is
HLodClass::Render
implemented correctly?