Reputation: 4427
Ok so what I'm trying to do is create an array of pointers that point to vectors that change in size. Also the array of pointers is nestled inside a class that's inside a vector. For some reason I seem to be having problems with memory becoming corrupt. Also if I use vectors I run into the problems with the stack overflowing caused by stuff resizing and calling constructors. Here is an essential layout of what I'm gunning for.
Maybe a little sloppy. But I end up with the problem of memory being currupted in the babyclasses pointers, basically I want to access "linked" babyclasses via the babyclasses vector of babyclasses it's connected to. Any clever ideas here?
And before anyone tells me this is a silly way to do things, isn't this type of functionality the basis of OO Programming?
class Baby
{
public:
deque<shared_ptr<Baby>> vInputs;
int X;
int Y;
int Z;
Baby()
{
numInputs = 0;
isNull = false;
wasTickled = false;
X,Y,Z = 0;
}
void addInput(shared_ptr<Baby> baby)
{
if(numInputs == 0)
vInputs = deque<shared_ptr<Baby>>(0);
vInputs.push_back(baby);
numInputs++;
}
void setXYZ(int x, int y, int z)
{
X = x;
Y = y;
Z = z;
}
void Tickle()
{
if(!wasTickled)
wasTickled = true;
else
return;
for(int i=0;i<numInputs;i++)
{
vInputs[i]->Tickle();
}
}
void setNull(bool isnull)
{
isNull = isnull;
}
private:
int numInputs;
bool isNull;
bool wasTickled;
};
class BabyLayer
{
public:
int Width;
int Height;
BabyLayer()
{
Width = 0;
Height = 0;
}
BabyLayer(int width, int height)
{
Width = width;
Height = height;
vecBabies = std::deque<deque<Baby>>(0);
for(int i=0;i<height;i++)
{
deque<Baby> row = deque<Baby>(0);
for(int i=0;i<width;i++)
{
row.push_back(Baby());
};
vecBabies.push_back(row);
}
MakeConnections();
}
Baby * getBaby(int x, int y)
{
Baby n = Baby();
n.setNull(true);
if(x >= Width || x <0)
return &n;
if(y >= Height || y < 0)
return &n;
n.setNull(false);
return &vecBabies[y][x];
}
~BabyLayer(void)
{
}
private:
std::deque<deque<Baby>> vecBabies;
void MakeConnections()
{
for(int y=0;y<Height;y++)
{
for(int x=0;x<Width;x++)
{
//Top Right
if(y > 0 && x < Width-1)
vecBabies[y][x].addInput(shared_ptr<Baby>(&vecBabies[y-1][x+1]));
//Middle Right
if(x < Width -1)
vecBabies[y][x].addInput(shared_ptr<Baby>(&vecBabies[y][x+1]));
//Bottom Right
if(x < Width -1 && y < Height-1)
vecBabies[y][x].addInput(shared_ptr<Baby>(&vecBabies[y+1][x+1]));
//Bottom Middle
if(y < Height-1)
vecBabies[y][x].addInput(shared_ptr<Baby>(&vecBabies[y+1][x]));
}
}
}
};
class BabyCube
{
public:
int X;
int Y;
int Z;
BabyCube(int x, int y, int z)
{
X = x;
Y = y;
Z = z;
Layers = deque<BabyLayer>();
for(int i=0;i<z;i++)
{
BabyLayer lay = BabyLayer(x,y);
Layers.push_back(lay);
}
NullBaby = Baby();
NullBaby.setNull(true);
MakeConnections();
}
void MakeConnections()
{
int l = Layers.size();
if(l == 0 || l == 1)
return;
for(int layer=0;layer<l;layer++)
{
BabyLayer * lay = &Layers[layer];
if(layer< l-1)
{
for(int y=0;y<lay->Height;y++)
{
for(int x=0;x<lay->Width;x++)
{
//Top Left
if(x > 0 && y > 0)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x-1,y-1)));
//Top Middle
if(y > 0)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x,y-1)));
//Top Right
if(y > 0 && x+1 < lay->Width-1)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x+1,y-1)));
//Middle Right
if(x+1 < lay->Width -1)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x+1,y)));
//Bottom Right
if(x+1 < lay->Width -1 && y+1 < lay->Height-1)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x+1,y+1)));
//Bottom Middle
if(y+1 < lay->Height-1)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x,y+1)));
//Bottom Left
if(x > 0 && y+1 < lay->Height-1)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x-1,y+1)));
//Middle Left
if(x > 0)
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x-1,y)));
//Middle Middle
Layers[layer].getBaby(x,y)->addInput(shared_ptr<Baby>(Layers[layer+1].getBaby(x,y)));
}
}
}
}
}
Baby * getBaby(int x, int y, int z)
{
if(z >= Layers.size() || z < 0)
return &NullBaby;
if(y >= Layers[z].Height || y < 0)
return &NullBaby;
if(x >= Layers[z].Width || x < 0)
return &NullBaby;
return Layers[z].getBaby(x,y);
}
void Update()
{
}
~BabyCube(void)
{
}
private:
deque<BabyLayer> Layers;
Baby NullBaby;
};
Upvotes: 1
Views: 345
Reputation: 2193
Out of morbid curiosity, I revisited this question to see if anyone had deciphered it.
The only obvious issue I see with the source code is in BabyLayer::GetBaby():
Baby n = Baby();
n.setNull(true);
if(x >= Width || x <0)
return &n; // Bad.
if(y >= Height || y < 0)
return &n; // Bad.
You're declaring a new Baby instance on the stack, then returning a pointer to it. The Baby instance named 'n' gets destructed when GetBaby() returns, and the returned pointer is now invalid.
I don't know what compiler you're using, but Visual Studio 2010 emits, "warning C4172: returning address of local variable or temporary" on these lines. Note that your code sample is incomplete and doesn't actually do anything, I had to declare a BabyCube instance to receive this warning.
Since I can't decipher what your code is supposed to do, and can make no sense of its operation, I can't explain why the memory access exceptions are thrown.
Upvotes: 2