1

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.

Diagram

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;
};
32
  • 1
    Is this a fixed size array of pointers in your class? How are you determining the size of the array and initializing the array? Post some code please. Commented Apr 30, 2011 at 1:00
  • 2
    "Ok so what I'm trying to do is create an array of pointers that point to vectors that change in size" "isn't this type of functionality the basis of OO Programming" No. Commented Apr 30, 2011 at 1:05
  • 5
    Having examined your diagram for a few minutes, I have to say that it makes absolutely no sense. Commented Apr 30, 2011 at 1:23
  • 2
    @kelton52: They have no such restrictions. If you're having problems there, you're simply using them incorrectly. Post the code, please. There's little we can say about your code if we cannot see it. Commented Apr 30, 2011 at 1:31
  • 2
    @kelton52: I do not consider that random blog to be authoritative. Using containers in the most indirect and convoluted fashion possible is most certainly not "the basis of OO programming", no matter what it says. Commented Apr 30, 2011 at 1:34

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah, I'm not sure why I did that. Completely missed it.
By the way, if you're curious(or maybe frightened), this was an attempt at a neural network. I got it working awhile ago after giving my head a few days to clear(always seems to help when ur stuck, you can make the stupidest mistakes^^^). Anyways I'm giving you the check cause you found a problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.