0

So I've encountered some problem in C++ (my first programming language was C).

Let's say I have the following classes:

2 headers (rectangle and grid, assume that point class is fine and another assumption is that we don't need print functions currently)

Grid.h

#ifndef GRID_H
#define GRID_H
#ifndef RECT_H
#include "Rectangle.h"

#endif

class Grid
{
public:
    Grid(int tileW, int tileH, int width, int height, int color);
    ~Grid();
    Rectangle& getRectAt(const Point &p);
    void print() const;
private:
    int count;
    Rectangle **recs;
};
#endif

Rect.h

#ifndef RECT_H
#define RECT_H
#ifndef POINT_H
#include "Point.h"
#endif

class Rectangle
{
public:
        Rectangle(int l, int u, int w, int h, int color);
        int getColor() const;
        void setColor(int color);
        bool contains(const Point &p) const;
        void print() const;
private:
        const Point topLeft, bottomRight;
        int color;
};

#endif

and the 2 cpp's:

Rect.cpp

#include "Rectangle.h"

Rectangle::Rectangle(int l, int u, int w, int h, int color) : topLeft(l, u), bottomRight(l + w, u + h) { this->color = color; }

int Rectangle::getColor() const
{
    return this->color;
}

void Rectangle::setColor(int color)
{
    this->color = color;
}

bool Rectangle::contains(const Point &p) const
{
    return (this->topLeft.getX < p.getX && p.getX < this->bottomRight.getX
        && this->bottomRight.getY < p.getY && p.getY < this->bottomRight.getY);
}

void Rectangle::print() const
{
    /**/
}

Grid.cpp

#include "Grid.h"

Grid::Grid(int tileW, int tileH, int width, int height, int color)
{
    int index, index_c=0;
    recs = new Rectangle *[width];

    for (int index = 0; index < width; index++)
    {
        recs[index] = new Rectangle [height];
    }

}

(assume that we don't need the other Grid functions and the constructor isn't finished).
Now what I'm trying to do is this, in Grid.cpp constructor, I'm trying to dynamically allocate the Array of Arrays but I just can't understand the logic behind the memory allocation of classes in cpp. I would appreciate if some one could explain me how the 'new' functions in cpp on classes and on n-dimensional arrays (of classes and in general).

I hope you understood the problem that I encounter here.

Thanks in advance.

eddie
  • 1,252
  • 3
  • 15
  • 20
Itay.V
  • 169
  • 1
  • 7
  • 2
    Do not use raw pointers and `new` / `delete` in c++. Use containers and smart pointers instead. – πάντα ῥεῖ Nov 21 '16 at 19:52
  • Regarding: "assumption is that we dont need print functions currently" Rather than making assumptions, remove the code and prove it to be true. Not only will you have the satisfaction of being right, you will have a smaller bug-hunting surface area and be one step closer to the [mcve] required for this question to be on-topic. – user4581301 Nov 21 '16 at 20:05
  • Not quite a duplicate, but a better direction to go: [Initializing a two dimensional std::vector](http://stackoverflow.com/questions/17663186/initializing-a-two-dimensional-stdvector) – user4581301 Nov 21 '16 at 20:13

2 Answers2

0
Grid::Grid(int tileW, int tileH, int width, int height, int color)  // האם ניתן להניח את תקינות הקלט ? 
{
  int i ,j ; 
  i=0;
  count=height*width;
  recs=new Rectangle* [count];
 
  for(i=0;i<count;i++)
   for(j=0;j<width;j++)
    {
        recs[i+j]=new Rectangle (tileW*j,tileH*i,tileW,1,tileH);
    }

}

You need to use 1 long array and address it like 2 dimensional.

benz
  • 177
  • 1
  • 1
  • 8
  • Yeah but If we be talking about n-dimension array you won't be able to follow up your indexing, so I'll rather find a solution of how to split it into array of arrays if there is one of course. – Itay.V Nov 21 '16 at 20:33
  • I not sure it possible without the default constructor – benz Nov 21 '16 at 20:37
0

as mentioned in the comments its better / easier to use some container template like:

                vector< Rectangle >     recs_1D;
        vector< vector< Rectangle > >   recs_2D;
vector< vector< vector< Rectangle > > > recs_3D;

Where vector<T> is any container class template of self allocating 1D array like std::vector. Just be sure that for nested templates you got space after < and before > otherwise some compilers might throw an syntax error.

You can even create your own container like this see:

And look for List_static template (there is full code) its static (so no dynamic allocations for simplicity) but you can use it as a template code to add the dynamic allocations to it.

How ever if you insist on using new,delete (which is in some cases faster/better/safer/necessary) than relay on 3th party template code its like this (writing directly in here so it might contain typos and In order to make it simple and fast You need to have defined rectangle constructor without operands Rectangle::Rectangle(){} !!!):

// some variables for 2D grid
int xs=0,ys=0;                // size of 2D grid [rectangles]
Rectangle **rec=NULL;

// allocation
xs=100; ys=50;                // wanted size
rec=new Rectangle*[xs];       // pointers for each column
rec[0]=new Rectangle[xs*ys];  // whole grid xs*yus rectangles (and also the first column)
for (int x=1;x<xs;x++)        // set all pointers to point to their column
 rec[x]=rec[x-1]+ys;

// now you can use rec[x][y]
rec[3][7]=Rectangle(3,7,1,1,55);

// releasing of memory
if (rec)
 {
 if (rec[0]) delete[] rec[0]; // release the grid
 delete[] rec;                // release pointers
 }
xs=0; ys=0; rec=NULL;

In case you can not use constructor without operands (for any reason) then you need to change the new/delete[] of rec[0] to 2 nested for (x,y) loops and use rec[x][y] instead which would be much slower and trashing the heap and C++ engine memory management.

You can use this in any dimensionality... Just add * to pointer, add resolution variable and another for loop for each axis and also one new,delete[]...

Spektre
  • 49,595
  • 11
  • 110
  • 380