   Segfaulting on Virtual Method Calls[SOLVED]
  Hey guys,I am doing  ROAM function, but right now i am having the trouble that i am getting an Access Violation when i try to call them from the class instances.This is the code i am making the array of classes in, a 16x16 2D array of patches, and also the methods i am going to need to call.But even before i get to those problems i am having trouble just calling the Init function from this terrain class...#ifndef TERRAIN_H#define TERRAIN_H#include "patch.h"#define MAX(a,b) ((a < b) ? (b) : (a))extern Vector3 position;class Landscape{public:static TreeNode *AllocateTri();//Allocate a new Tri Tree Node for the mesh//static TreeNode *AllocateTri();virtual void Init(unsigned char *heightMap);//Render terrainvirtual void Render();virtual void Reset();//Create Mesh approximationvirtual void Tessellate();//Get and Set next TreeNodestatic int GetNextTreeNode() {return m_nextNode;}static void SetNextTreeNode(int nextNode) {m_nextNode = nextNode;}protected:unsigned char *m_heightMap;//Patches Per Side * Patches Per SidePatch m_patches[16][16];//Index to the next treenodestatic int m_nextNode;//Pool of splitting nodesstatic TreeNode m_nodePool[64000];};#endifHere are the functions that are being called, i am having trouble through the whole thing, i can't call any of the virtual methods inside of my Patch class either, but i can cross that bridge when i come to it./Static Member variablesint Landscape::m_nextNode;TreeNode Landscape::m_nodePool[64000];//Allocate a Treenode from poolTreeNode *Landscape::AllocateTri(){TreeNode *pNode;//If we run out ot nodes, return Nullif(m_nextNode >= 64000/*Pool Size of nodes*/)return NULL;pNode = &(m_nodePool[m_nextNode++]);pNode->LeftChild = pNode->RightChild = NULL;return pNode;}//Initialise all patchesvoid Landscape::Init(unsigned char *heightMap){Patch *patch;int x, y;//m_patches = new Patch [/*Patches per side*/16][16];//Store hiegtmapm_heightMap = heightMap;//initialise all terrain patchesfor(y = 0; y < 16/*NUM PATCHES PER SIDE*/; y++){for(x = 0; x < 16; x++){patch = &(m_patches[y][x]);patch->Init(x * 64 /*Patch Size*/, y * 64, x * 64, y * 64, m_heightMap);printf("BLAH %d %d\n", y, x);patch->ComputeVariance();}}}void Landscape::Tessellate(){int count;Patch *patch = &(m_patches[0][0]);for(count = 0; count < 16/*Num patches per side*/ * 16; count++, patch++){patch->Tessellate();}}void Landscape::Render(){int count;Patch *patch = &(m_patches[0][0]);for(count = 0; count < 16 * 16/*Num patches per side*/; count++, patch++){patch->Render();}}void Landscape::Reset(){int X, Y;Patch *patch;// Set the next free triangle pointer back to the beginningSetNextTriNode(0);// Go through the patches performing resets, compute variances, and linking.for ( Y=0; Y < 16; Y++ )for ( X=0; X < 16; X++){patch = &(m_Patches[Y][X]);// Reset the patchpatch->Reset();// Check to see if this patch has been deformed since last frame.// If so, recompute the varience tree for it.if ( patch->isDirty() )patch->ComputeVariance();// Link all the patches together.if ( X > 0 )patch->GetBaseLeft()->LeftNeighbor = m_Patches[Y][X-1].GetBaseRight();elsepatch->GetBaseLeft()->LeftNeighbor = NULL;// Link to bordering Landscape here..if ( X < (16-1) )patch->GetBaseRight()->LeftNeighbor = m_Patches[Y][X+1].GetBaseLeft();elsepatch->GetBaseRight()->LeftNeighbor = NULL;// Link to bordering Landscape here..if ( Y > 0 )patch->GetBaseLeft()->RightNeighbor = m_Patches[Y-1][X].GetBaseRight();elsepatch->GetBaseLeft()->RightNeighbor = NULL;// Link to bordering Landscape here..if ( Y < (15-1) )patch->GetBaseRight()->RightNeighbor = m_Patches[Y+1][X].GetBaseLeft();elsepatch->GetBaseRight()->RightNeighbor = NULL;// Link to bordering Landscape here..}}Any help here would be great, it is a recursive algorithm and i would love to be able to call virtual functions...because then it would work, any help would be great. Thank You[Edited by - Deftoned on August 21, 2008 11:00:01 PM]
  Are you supplying an heightmap to the init-function?   ;  Yes, the actual problem that i have noticed is say:Landscape land;land.Init(heightMap);land will have a memory address but Init has no memory addresssame with PatchPatch->ComputerVariance();Patch will have a memory addressComputeVariance won't have a memory address;  That error is usually caused by overwriting the first 4 bytes of the class with 0 (or some other invalid value). It's only a problem on classes with virtual functions.For example doing memset(this, 0, sizeof(*this)) will cause it.Also watch out for negative or otherwise out of bounds array indices (for example writing to m_patches[-1][-1] or m_patches[16][16]).If you don't see the error yourself then a data breakpoint on the class should find the code that writes to that address.[Edited by - Adam_42 on August 21, 2008 8:07:19 AM];  I don't know exactly what i did but i got Landscape virtual functions working, but still having problems getting virtual functions from patch.h working, i am not allocating any memory dynamically i think all of it is hardcoded, here is patch .h#ifndef PATCH_H#define PATCH_H#include "../Vector3/Vector3.h"class Landscape;struct TreeNode{TreeNode *LeftChild;TreeNode *RightChild;TreeNode *BaseNeighbor;TreeNode *LeftNeighbor;TreeNode *RightNeighbor;}; class Patch{public:TreeNode *GetBaseLeft() {return  &m_BaseLeft;}TreeNode *GetBaseRight() {return &m_BaseRight;}char isDirty(){return m_VarianceDirty;}int  isVisibile() {return m_isVisible;}void SetVisibility(int eX, int eY, int lX, int lY, int rX, int rY);//Reset for next framevirtual void Init(int x, int y, int wX, int wY, unsigned char *heightMap);virtual void Reset();virtual void Tessellate();//Create Meshvirtual void Render();//Update for height map changesvirtual void ComputeVariance();// The recursive half of the Patch Classvirtual voidSplit(TreeNode *triNode);virtual voidRecursTessellate(TreeNode *triNode, int lX, int lY, int rX, int rY, int aX, int aY, int node );virtual voidRecursRender(TreeNode *triNode, int lX, int lY, int rX, int rY, int aX, int aY );virtual unsigned charRecursComputeVariance(int lX,  int lY,  unsigned char lZ,int rX, int rY, unsigned char rZ,int aX,  int aY,  unsigned char aZ,int node);protected:unsigned char *m_heightMap;// Pointer to height map to useint m_WorldX, m_WorldY;// World coordinate offset of this patch.unsigned char m_VarianceLeft[1<<(9)];// Left variance treeunsigned char m_VarianceRight[1<<(9)];// Right variance treeunsigned char *m_CurrentVariance;// Which varience we are currently using. [Only valid during the Tessellate and ComputeVariance passes]unsigned char m_Updated;// Does the Varience Tree need to be recalculated for this Patch?unsigned char m_isVisible;// Is this patch visible in the current frame?unsigned char m_VarianceDirty;TreeNode m_BaseLeft;// Left base triangle tree nodeTreeNode m_BaseRight;// Right base triangle tree node};#endif;  Memory overwrite bugs can be very sensitive to code changes - even fairly small changes can move the bit of memory they are trashing, making the bug seem to go away or move.What you need to do is find a reliable reproduction method without changing the code, work out at which address memory has been trashed, and set a data breakpoint on that address and rerun it. That will show you the line of code that has written to that address and you can then fix it (or run through to the next write if that one wasn't the problem).Looking at that header file my best guess would be that the m_VarianceLeft array has been accessed with a negative array index, but it could be from anywhere.You can easily range check array indices using a template. Something like this should do the trick:template <typename T, size_t Size>class CheckedArray{public:  T & operator[](int index)  {    assert(index >= 0 && index < Size);    return m_data[index];  }protected:  T m_data[Size];};;  Thank you very much, i will give this a try and get back with what happens. Cheers.   