Ghost instances popping up in vectors

This one has me stumped. I have three classes - a large class called Level that contains, among other things, a multidimensional vector of pointers to Plant instances and a multidimensional vector of pointers to Mob instances; both vectors are meant to classify the mobs and plants according to their position, so that I can search for each in a smaller vector based on their approximate location, rather than cycling through all existing plants/mobs in order to find the one nearest to a given point.

The vectors are as follows, with the smallest std::vectors representing a square area of 128 pixels on each side. Mobs and plants are classed by dividing their X and Y coords by 128 and adding them to the proper sector (I am careful that the resulting values are in fact integers).

std::vector< std::vector< std::vector<Plant*> > >* m_PlantSectors

std::vector< std::vector< std::vector<Mob*> > >* m_AnimalSectors

The mobs sometimes need to find plants. Here is where the problem arises: when the mobs query the multidimensional vector, searching for plants in their approximate area (if the mob's coords/128 are, say, [1,2] it searches m_PlantSectors[2][1]), they sometimes find plants that don't exist.

Not only that, but these plants have impossible positions, on the order of 1.9777e+33 or 3.75853e-39 (for instance). When I try to change the color of the chosen plant to red in order to find it visually, I find that none of the plants on the screen (the only plants are ones I've hand-placed) have changed color.

I've marked all the plants with an integer ID; there are 36 plants, with IDs from 1-36, but the plants my mobs find have IDs like 63 or 429 - ones that can't possibly exist, since no such number of plants was created (there is a single plant creation function that consistently reports how many plants exist, so no plants are being accidentally created). The mobs all run off to the upper-left part of the screen after the imaginary plants, and die of starvation.

So somehow, I an creating ghost plants. So far, I've tried two separate approaches for allowing Mob instances to look for Plant instances. The first looks like this:

    float TargetDist = 256 * 256;
    Plant* Candidate = 0;
    Plant* ForageTarget = 0;
    int xSect = m_X / 128;
    int ySect = m_Y / 128;
    std::vector<Plant*> ThisSect = pLevel->CheckPSector(xSect, ySect);
    for (int i = 0; i < ThisSect.size(); ++i)
    {
        cout << "Searching in Sector (" << ySect << ", " << xSect << ")\n";
        Candidate = ThisSect[i];
        cout << "Candidate at: " << Candidate->GetX() << ", " << Candidate->GetY() << "\n";
        Candidate->Mark();
        //Calculate distance
        float xDist = Candidate->GetX() - m_X;
        float yDist = Candidate->GetY() - m_Y;
        float tDist = sqrt(xDist * xDist + yDist * yDist);
        if (tDist <= TargetDist)
        {
            ForageTarget = Candidate;
            TargetDist = tDist;
        }
    }

Where CheckPSector() looks like this:

std::vector<Plant*> Level::CheckPSector(int x, int y)
{
    return m_PlantSectors[y][x];
}

The second thing I tried was this:

        float TargetDist = 256 * 256;
        Plant* Candidate = 0;
        Plant* ForageTarget = 0;
        int xSect = m_X / 128;
        int ySect = m_Y / 128;
        std::vector< std::vector< std::vector<Plant*> > >* Sectors = pLevel->AccessPlantSectors();
        for (int i = 0; i < (*Sectors)[ySect][xSect].size(); ++i)
        {
            cout << "Searching in Sector (" << ySect << ", " << xSect << ")\n";
            Candidate = (*Sectors)[ySect][xSect][i];
            cout << "Candidate at: " << Candidate->GetX() << ", " << Candidate->GetY() << "\n";
            Candidate->Mark();
            //Calculate distance
            float xDist = Candidate->GetX() - m_X;
            float yDist = Candidate->GetY() - m_Y;
            float tDist = sqrt(xDist * xDist + yDist * yDist);
            if (tDist <= TargetDist)
            {
                ForageTarget = Candidate;
                TargetDist = tDist;
            }
        }

Using this:

std::vector< std::vector< std::vector<Plant*> > >* Level::AccessPlantSectors()
{
    return &m_PlantSectors;
}

Both of these, however, result in the animals finding imaginary plants and running off into the void.

I don't want to copy potentially large multidimensional vectors into Mob instances on a regular basis, because there will be many such instances at any one time, and I'd like the program to run somewhat smoothly. Even so, I just tried to do the whole thing by copying the entire vector instead of just the relevant one, and I get the same result: imaginary plants.

I've never quite had a problem like this before; what could be happening here?

EDIT: Perhaps I should mention that getting the chosen plants to self-report their own position and ID fails equally, turning up absurd results, so it isn't just the functions in Plant I use to access private members. Meanwhile, querying all existing plants does not reveal any with the information the ghost plants self-report.

Answers


If m_PlantSectors is defined as:

std::vector< std::vector< std::vector<Plant*> > >* m_PlantSectors

Then Level::AccessPlantSectors() should return m_PlantSectors, not &m_PlantSectors because you already have a pointer.

Likewise, Level::CheckPSector(int x, int y) should return (*m_PlantSectors)[y][x] because you need to deference the pointer before invoking the [] operator.

As you've written them, Level::CheckPSector(int x, int y) returns random memory and I'm surprised that Level::AccessPlantSectors() compiles.


Need Your Help

Why catalina.home_IS_UNDEFINED directory is generated by Logback in the same project directory?

java tomcat playframework-2.0 logback

I have written logback configuration file for my application, but when I was doing maven clean install(mvn clean install), it generated a catalina.home_IS_UNDEFINED directory with log file in the p...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.