Page 1 of 1

<SOLVED>Define multidimensional array in a object

Posted: Mon Mar 01, 2010 5:20 pm
by mv2112
What im trying to do is create a multidimensional array whos size differs depending on what the user enters. I want to define the array when the object is declared in main but i cant figure it out.
Here is my code so far...

Code: Select all


#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

class object{
	//object base class
	int XMAX;
	int YMAX;
public:
	void set_char(char character);
	char r_char();
	char grid[YMAX][XMAX]; //Im trying to define YMAX and XMAX when the object is declared in the main function
	char* pgrid[YMAX][XMAX];
protected:
	int x;
	int y;
	int ox;
	int oy;
	char ch;
};

void object::set_char(char character){
	ch=character;
}

char object::r_char(){
	return ch;
}

class screen:public object{
public:
	void rend(char* a[YMAX][XMAX]);
};

void screen::rend(char* a[YMAX][XMAX]){
	*pgrid[oy][ox]=' ';
	*pgrid[y][x]=ch;
}

int main(){
object a(10,10); //now the array is supposed to be grid[10][10];
}
I get these errors everytime i use YMAX and XMAX
1>h:\headers\mvglib.h(21) : error C2327: 'object::YMAX' : is not a type name, static, or enumerator
1>h:\headers\mvglib.h(21) : error C2065: 'YMAX' : undeclared identifier
How can i change the size of the array for each declaration of the object?

Re: Define multidimensional array in a object

Posted: Mon Mar 01, 2010 5:32 pm
by Bakkon
You'll have to dynamically allocate memory for the arrays if the size is dependent on user input.

We recently had a thread about it here: http://thechaosrift.com/viewtopic.php?f ... art=999999

Re: Define multidimensional array in a object

Posted: Mon Mar 01, 2010 6:55 pm
by Falco Girgis
What you are trying to do is impossible without using dynamic memory. The problem is that the compiler allocates the array (and anything not allocated with new and delete) on the stack rather than the heap. This means that as soon as your object is instantiated with:

Code: Select all

object a(10,10); //now the array is supposed to be grid[10][10];
Memory is IMMEDIATELY allocated for the array grid[10][10];

Actually, I think I see what you were trying to do. So that right when it's allocated, it takes the dimensions of 10,10 through the constructor? That's pretty smart, but the problem is that the constructor is executed AFTER the object has been allocated on the stack. So at the time you're trying to define these dimensions, the grid[][] was supposed to already have been created. So unfortunately, that won't work.

Since you want the size of your array to be determined at runtime, you're going to need to declare your array like so:

Code: Select all

int **grid;
So now we have a pointer to a pointer to an integer. Now allocate the rows like so (in your constructor):

Code: Select all

grid = new int *[ROWS];
Now you have an array of pointers that is ROWS large. Next, each row has to point to an array of integers (for each column):

Code: Select all

for( int i = 0 ; i < ROWS ; i++ )
grid[i] = new int[COLUMNS];
Now you have a 2D array of a size that YOU specified at RUNTIME. This exists on the heap (rather than the stack) and may be used just like any 2D array:

Code: Select all

grid[i][j] = 20;
Now don't forget to delete it (in your destructor). You must loop through each row deleting the columns FIRST: (so you're deleting each array that the rows have (which are the columns)).

Code: Select all

for( int i = 0 ; i < ROWS ; i++ )
delete [] grid[i] ;
Then you delete the rows.

Code: Select all

delete [] grid;
If you don't remember to delete the memory that you allocated on the heap, you have a memory leak. And that sucks.

Re: Define multidimensional array in a object

Posted: Mon Mar 01, 2010 7:46 pm
by mv2112
GyroVorbis wrote:What you are trying to do is impossible without using dynamic memory. The problem is that the compiler allocates the array (and anything not allocated with new and delete) on the stack rather than the heap. This means that as soon as your object is instantiated with:

Code: Select all

object a(10,10); //now the array is supposed to be grid[10][10];
Memory is IMMEDIATELY allocated for the array grid[10][10];

Actually, I think I see what you were trying to do. So that right when it's allocated, it takes the dimensions of 10,10 through the constructor? That's pretty smart, but the problem is that the constructor is executed AFTER the object has been allocated on the stack. So at the time you're trying to define these dimensions, the grid[][] was supposed to already have been created. So unfortunately, that won't work.

Since you want the size of your array to be determined at runtime, you're going to need to declare your array like so:

Code: Select all

int **grid;
So now we have a pointer to a pointer to an integer. Now allocate the rows like so (in your constructor):

Code: Select all

grid = new int *[ROWS];
Now you have an array of pointers that is ROWS large. Next, each row has to point to an array of integers (for each column):

Code: Select all

for( int i = 0 ; i < ROWS ; i++ )
grid[i] = new int[COLUMNS];
Now you have a 2D array of a size that YOU specified at RUNTIME. This exists on the heap (rather than the stack) and may be used just like any 2D array:

Code: Select all

grid[i][j] = 20;
Now don't forget to delete it (in your destructor). You must loop through each row deleting the columns FIRST: (so you're deleting each array that the rows have (which are the columns)).

Code: Select all

for( int i = 0 ; i < ROWS ; i++ )
delete [] grid[i] ;
Then you delete the rows.

Code: Select all

delete [] grid;
If you don't remember to delete the memory that you allocated on the heap, you have a memory leak. And that sucks.
omg... :shock2:
VERRY COMPLICATED lol

Re: Define multidimensional array in a object

Posted: Mon Mar 01, 2010 7:49 pm
by mv2112
I gave up on regular arrays and i used multidimensional vectors instead. :mrgreen:
Here is the code:

Code: Select all


#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

class object{
	//object base class
public:
	void set_char(char character);
	char r_char();
	vector<vector<char>> grid;
	vector<vector<char*>> pgrid;
protected:
	int x;
	int y;
	int ox;
	int oy;
	char ch;
};

void object::set_char(char character){
	ch=character;
}

char object::r_char(){
	return ch;
}

class screen:public object{
public:
	void setup(int,int,char='m');
	void rend(vector<vector<char*>>pgrid);
	void disp();
	void edit(int x, int y, char a);
	int xx;
	int yy;
};

void screen::rend(vector<vector<char*>>pgrid){  //this function is useless right now
	*pgrid[oy][ox]=' ';
	*pgrid[y][x]=ch;
}

void screen::setup(int x, int y, char c){
	xx=x;
	yy=y;
	ch=c;
	grid.resize(y);
	pgrid.resize(y);
	for(int i=0;i<x;i++){
		for(int j=0;j<y;j++){
			grid[j].resize(x);
			grid[j][i]=ch;
			pgrid[j].resize(x);
			pgrid[j][i]=&grid[j][i];
		}
	}
}

void screen::disp(){
	for(int op=0;op<yy;op++){
		for(int j=0;j<xx;j++){
			cout<<grid[op][j];
		}
		cout<<endl;
	}
}

void screen::edit(int x, int y, char a){
	*pgrid[y][x]=a;
}

works PERFECTLY! 8-)

Re: Define multidimensional array in a object

Posted: Tue Mar 02, 2010 1:49 am
by ultimatedragoon69
I just wanted to say falco you explained that very well. I think it was incredibly easy to follow, have you thought about doing some tutorials?

Re: Define multidimensional array in a object

Posted: Tue Mar 02, 2010 7:07 am
by Falco Girgis
ultimatedragoon69 wrote:I just wanted to say falco you explained that very well. I think it was incredibly easy to follow, have you thought about doing some tutorials?
Yep. We are going to start as soon as the new site is constructed.

Re: Define multidimensional array in a object

Posted: Tue Mar 02, 2010 8:44 am
by XianForce
GyroVorbis wrote:
ultimatedragoon69 wrote:I just wanted to say falco you explained that very well. I think it was incredibly easy to follow, have you thought about doing some tutorials?
Yep. We are going to start as soon as the new site is constructed.
SWEEEEEET!!!!! Can't wait for them, it should be epic =D

Re: Define multidimensional array in a object

Posted: Tue Mar 02, 2010 12:48 pm
by ultimatedragoon69
Sounds like total win to me. Can't wait for it, i've never been good at tutorials but if you need any help let me know. :mrgreen:

Re: Define multidimensional array in a object

Posted: Tue Mar 02, 2010 1:56 pm
by mv2112
mv2112 wrote:
GyroVorbis wrote:What you are trying to do is impossible without using dynamic memory. The problem is that the compiler allocates the array (and anything not allocated with new and delete) on the stack rather than the heap. This means that as soon as your object is instantiated with:

Code: Select all

object a(10,10); //now the array is supposed to be grid[10][10];
Memory is IMMEDIATELY allocated for the array grid[10][10];

Actually, I think I see what you were trying to do. So that right when it's allocated, it takes the dimensions of 10,10 through the constructor? That's pretty smart, but the problem is that the constructor is executed AFTER the object has been allocated on the stack. So at the time you're trying to define these dimensions, the grid[][] was supposed to already have been created. So unfortunately, that won't work.

Since you want the size of your array to be determined at runtime, you're going to need to declare your array like so:

Code: Select all

int **grid;
So now we have a pointer to a pointer to an integer. Now allocate the rows like so (in your constructor):

Code: Select all

grid = new int *[ROWS];
Now you have an array of pointers that is ROWS large. Next, each row has to point to an array of integers (for each column):

Code: Select all

for( int i = 0 ; i < ROWS ; i++ )
grid[i] = new int[COLUMNS];
Now you have a 2D array of a size that YOU specified at RUNTIME. This exists on the heap (rather than the stack) and may be used just like any 2D array:

Code: Select all

grid[i][j] = 20;
Now don't forget to delete it (in your destructor). You must loop through each row deleting the columns FIRST: (so you're deleting each array that the rows have (which are the columns)).

Code: Select all

for( int i = 0 ; i < ROWS ; i++ )
delete [] grid[i] ;
Then you delete the rows.

Code: Select all

delete [] grid;
If you don't remember to delete the memory that you allocated on the heap, you have a memory leak. And that sucks.
omg... :shock2:
VERRY COMPLICATED lol
Actually, now that i have taken a closer look at what falco said, its not that complicated. I will have to try doing that and see how it compares with my vector way of doing it.

Re: Define multidimensional array in a object

Posted: Tue Mar 02, 2010 3:51 pm
by mv2112
Well, this is what iv been working on for two days lol. Makes text on console look cooler. You can put any char in a grid on the screen.
its not all done yet but here is a little program i made
it only works on windows

here is the mvGLIB.h

Code: Select all

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <time.h>
#include <windows.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#include <cstdlib>

using namespace std;

void MVcls(){
	system("cls");
}

class object{
	//object base class
public:
	void set_char(char character);
	char r_char();
	vector<vector<char>> grid;
	vector<vector<char*>> pgrid;
	void set_frate(int t);
	void frate();
	void set_color(int num);

protected:
	int x;
	int y;
	int ox;
	int oy;
	char ch;
	int time;
};

void object::set_char(char character){
	ch=character;
}

char object::r_char(){
	return ch;
}

void object::set_frate(int t){
	time=t;
}

void object::frate(){
	Sleep(time);
}

void object::set_color(int num){
	switch(num){
		case 1:
			system("color a");
			break;
		case 2:
			system("color b");
			break;
		case 3:
			system("color c");
			break;
	}
}

class screen:public object{
public:
	void setup(int,int);
	void rend(vector<vector<char*>>pgrid);
	void disp();
	void edit(int x, int y, char a);
	int r_x();
	int r_y();
private:
	int xx;
	int yy;
};

void screen::rend(vector<vector<char*>>pgrid){
	*pgrid[oy][ox]=' ';
	*pgrid[y][x]=ch;
}

void screen::setup(int x, int y){
	xx=x;
	yy=y;
	grid.resize(y);
	pgrid.resize(y);
	for(int i=0;i<x;i++){
		for(int j=0;j<y;j++){
			grid[j].resize(x);
			grid[j][i]=ch;
			pgrid[j].resize(x);
			pgrid[j][i]=&grid[j][i];
		}
	}
}

void screen::disp(){
	MVcls();
	for(int i=0;i<yy;i++){
		for(int j=0;j<xx;j++){
			cout<<grid[i][j];
		}
		cout<<endl;
	}
}

void screen::edit(int x, int y, char a){
	*pgrid[y][x]=a;
}

int screen::r_x(){
	return xx;
}

int screen::r_y(){
	return yy;
}
and here is the main.cpp:

Code: Select all


#include "mvGLIB.h"

int main(){
	screen test;
	test.set_char(' ');
	test.setup(20,20);
	test.set_frate(50);
	MVcls();
	char m='m';
	char i='i';
	char k='k';
	char e='e';

	char M=m;
	char I=i;
	char K=k;
	char E=e;

	int color=1;
	test.edit(3,2,'M');

	while (1==1){
	M=m;
	I=i;
	K=k;
	E=e;
	test.set_color(color);

	if(color<3){
		color++;
	}
	else{
		color=1;
	}

	test.edit(0,0,m);
	test.edit(0,1,i);
	test.edit(0,2,k);
	test.edit(0,3,e);
	test.edit(0,4,m);
	test.edit(1,4,i);
	test.edit(2,4,k);
	test.edit(3,4,e);
	test.edit(4,4,m);
	test.edit(5,4,i);
	test.edit(6,4,k);
	test.edit(6,3,e);
	test.edit(6,2,m);
	test.edit(6,1,i);
	test.edit(6,0,k);
	test.edit(5,0,e);
	test.edit(4,0,m);
	test.edit(3,0,i);
	test.edit(2,0,k);
	test.edit(1,0,e);

	test.disp();

	m=E;
	i=M;
	k=I;
	e=K;
	test.frate();
	MVcls();
	}

	system("pause");
}


Re: Define multidimensional array in a object

Posted: Wed Mar 03, 2010 2:50 pm
by Zer0XoL
Make XMAX and YMAX const and then do it like:

Code: Select all

classname(int x, int y) : XMAX(x), YMAX(y) //construcor
{
}