0

I have a 2D fixed size object array of "spot" class Spot map[row][col];//row & col are dynamic changed integer I want to pass it to a function bool isFilled(int row,int col,Spot[row][col]){} How to define the function? How to delete this array ?Please see my code. Thanks for your help.

Spot.h

    #ifndef SPOT_H
#define SPOT_H

class Spot
{
private:
    bool isBunny;
    int nextCycle;
public:
    static const int UP = 0;
    static const int RIGHT = 1;
    static const int DOWN = 2;
    static const int LEFT = 3;
    static const int SLEEP = 4;

    virtual void setSpot(bool newIsBunny);
    Spot();
    ~Spot();
    virtual int getNextCycle();
    virtual void setNextCycle();
    virtual bool getIsBunny();
    virtual void makeBunny();
};

void Spot::setSpot(bool newIsBunny)
{
    isBunny = newIsBunny;
    nextCycle = UP;
}

Spot::Spot()
{
    isBunny = false;
    nextCycle = UP;
}

Spot::~Spot()
{
}

void Spot::setNextCycle()
{
    if (nextCycle != SLEEP)
    {
        nextCycle++;
    }
}

int Spot::getNextCycle()
{
    return nextCycle;
}

bool Spot::getIsBunny()
{
    return isBunny;
}

void Spot::makeBunny()
{
    if (!isBunny)
        nextCycle = UP;
    isBunny = true;
}


#endif  /* SPOT_H */


Bunny.cpp



#include "Spot.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <boost/algorithm/string.hpp>


using namespace std;


static string line;
static ifstream inFile;
static ofstream outFile;
bool isFilled(int x, int y, Spot **myMap);

int main () {
  int numSims = 0;
  inFile.exceptions ( ifstream::failbit | ifstream::badbit );

  try {
    inFile.open ("/home/mike/Desktop/input.txt");
    outFile.open ("/home/mike/Desktop/output.txt");
   // while(!inFile.eof())
      {

         getline (inFile,line);
        numSims= atoi(line.c_str());
       //cout<<"numSims: "<<numSims<<endl;
        for (int i = 0;i < numSims;i++)
            {
                int minPerCycle = 1;
                getline (inFile,line);
                minPerCycle= atoi(line.c_str());

            //cout << "minPerCycle: "<<minPerCycle <<endl;

                int row = 0;
                int col = 0;
                    getline (inFile,line);
                    std::vector<std::string> xy;
                    boost::split(xy, line, boost::is_any_of(" "));
                    row=atoi(xy.at(0).c_str());
                    col=atoi(xy.at(1).c_str());
                    //cout <<"row: "<< row<<endl;
                    //cout << "col: "<<col<<endl;


                    Spot** myMap = new Spot* [col];
                    for(int i = 0; i < col; ++i)
                        myMap[i] = new Spot [row];

                    //std::vector<std::vector<Spot> > myMap(x, std::vector<Spot>(y));
                    for (int i = 0;i < row;i++)
                            {
                                getline (inFile,line);
                                //cout<<line<<endl;
                                for (int j = 0;j < col;j++)
                                {
                                    if (line[j] == 'B')
                                    {
                                        myMap[i][j].setSpot(true);

                                    }
                                    else
                                    {
                                        myMap[i][j].setSpot(false);

                                    }
                                }
                            }
                int numCycles = 1;

                if (isFilled(row,col,myMap))
                {
                    numCycles = 0;
                }

                while (!isFilled(row,col,myMap))
                {
                    numCycles++;

                    for (int j = 0;j < row;j++)
                    {
                        for (int k = 0;k < col;k++)
                        {
                            if (myMap[j][k].getIsBunny())
                            {       //cout<< j<<" "<<k<<" " <<"true"<<endl;
                                    switch (myMap[j][k].getNextCycle())
                                    {
                                        case Spot::UP :
                                            if (j>0)
                                            myMap[j-1][k].makeBunny();
                                            break;
                                        case Spot::RIGHT :
                                            if (k<col-1)
                                            myMap[j][k + 1].makeBunny();
                                            break;
                                        case Spot::DOWN :
                                            if (j<row-1)
                                            myMap[j+ 1][k].makeBunny();
                                            break;
                                        case Spot::LEFT :
                                            if (k>0)
                                            myMap[j][k - 1].makeBunny();
                                            break;
                                    }
                                    myMap[j][k].setNextCycle();
                                }
                            //cout<< j<<" "<<k<<" " <<"outside"<<endl;
                        }
                    }

                }
                int time = numCycles*minPerCycle;
                outFile<<"It took " <<time <<" minutes for the bunnies to take over the world!\n";
                cout<<"It took " <<time <<" minutes for the bunnies to take over the world!\n";
                for(int i=0; i < col; i++) {
                   delete [] myMap[i];
                }
                delete myMap;

            }
      }

       inFile.close();
       outFile.close();

}
  catch (ifstream::failure e) {
    cout << "Exception opening/reading file";
  }

  return 0;
}


bool isFilled(int row, int col,Spot **myMap)
{
    for (int i = 0;i < row;i++)
    {
        for (int j = 0;j < col;j++)
        {
            if (!myMap[i][j].getIsBunny())
            {
                //cout<<"true ";
                return false;

            }
            //else
            //  cout<<"false ";


        }
        //cout<<endl;

    }
    return true;
}
Mike
  • 497
  • 1
  • 5
  • 7
  • 4
    There's a lot of noise in the code. If all you're asking is how to pass a 2d array as parameter, you can illustrate this with a 2-line example. Please do so! – Luchian Grigore Sep 26 '12 at 07:40
  • Pass a 2d array [___by reference___](http://stackoverflow.com/a/404247/1019491). Pass a 2d array [___by pointer___](http://stackoverflow.com/a/2308863/1019491). There, done! – Hindol Sep 26 '12 at 07:49
  • 2
    Please supply a [sscce](http://sscce.org/) – default Sep 26 '12 at 07:56

3 Answers3

0

Have to tried passing with pointers?

static bool isFilled(int row, int col,Spot** yourMap)

I'm unsure if Spot myMap[row][col] will be accepted by the compiler as row and col seem to be set at runtime.

You may need to allocate memory in the following manner

Spot** myMap = new Spot* [col];
for(int i = 0; i < col; ++i)
    myMap[i] = new Spot [row];

Deleting the memory would require you to use a similar for loop but remember to call delete []

home_monkey
  • 79
  • 1
  • 5
  • `Spot myMap[row][col]` is illegal in C++. Some compilers accept it as an extension because this is legal in C99. However, there is no way to pass these non-standard 2D arrays to a function in C++. Passing as `Spot **` does not work. These are not ragged arrays. They are contiguous arrays. – David Hammen Sep 26 '12 at 08:33
  • @David Hammem - thanks for the information. I think I'll be experimenting with this later today to improve my understanding. Would 'int blah[xxx][xxx]' valid and 'MyClass blah[xxx][xxx] invalid'? No need to answer this, I'll disover this soon. – home_monkey Sep 26 '12 at 08:54
  • The problem is that `row` and `col` are variables. C99 has a concept of variable length arrays. It is legal in C99 to declare an array with dimensions defined at runtime. This concept of variable length arrays did not exist in C++98/C++03. It was proposed for C++11, but that proposal was smacked down (smacked down hard!) as being against the grain of C++. – David Hammen Sep 26 '12 at 09:44
0

I think you can just send a reference to the 2D array into the method you want to use the 2D array with.

bool isFilled(int row, int col, Spot &m){  // if you want a fix position in the array
 // Code
}

If you want to delete the array you have to use the delete operator.

First you have to delete all the arrays which the pointer array points to, ie

for(int i=0; i < size; i++) {
   delete [] spot[i];  // Depends on what you have called the array
}

Then you have to delete the array of pointers with

delete [] spot;   
Destidom
  • 97
  • 5
0

Spot myMap[row][col];

This is not legal C++ code. You can do this in C99 but not in C++.

You have two basic choices in C++:

  1. Use a one dimensional array that you treat as if it were a 2D array.
  2. Use a ragged 2D array instead of a contiguous 2D array.

The key advantage of using a one dimensional array is that it is fast. This is the way to go if you need speed. Graphics programmers often use this approach because they need that speed. The downside is that you have to convert your 2D indices to a single index. For example, map[i][j] might become map[i*col+j] (row major order) or map[i+j*row] (column major order).

The key advantage of using a ragged array is that the indexing is natural. The downsides are that there are many more pieces of memory to manage and access is considerably slower. With a flattened array, access comprises a small number of integer operations and a single memory lookup. The ragged array requires two memory lookups.

This is C++, so my suggestion is to make your map a class. Provide a non-default constructor with a row and column size that allocates the memory, a destructor (if needed) to clean up. If you use std::vector as the underlying storage mechanism, it will do the allocation and cleanup for you. Provide an overload of operator() to act as an index mechanism into your map. Now the mechanism that you are using to represent your map is hidden. You can start with a vector of vectors, and if that's too slow, switch to the flattened array approach.

David Hammen
  • 32,454
  • 9
  • 60
  • 108