<SOLVED>Define multidimensional array in a object

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

<SOLVED>Define multidimensional array in a object

Post 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?
Last edited by mv2112 on Wed Mar 03, 2010 8:11 pm, edited 2 times in total.
User avatar
Bakkon
Chaos Rift Junior
Chaos Rift Junior
Posts: 384
Joined: Wed May 20, 2009 2:38 pm
Programming Language of Choice: C++
Location: Indiana

Re: Define multidimensional array in a object

Post 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
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Define multidimensional array in a object

Post 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.
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: Define multidimensional array in a object

Post 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
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: Define multidimensional array in a object

Post 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-)
User avatar
ultimatedragoon69
Chaos Rift Regular
Chaos Rift Regular
Posts: 122
Joined: Tue Oct 28, 2008 1:57 pm
Current Project: Pangea's quest (text ~tile~ based rpg)
Favorite Gaming Platforms: Dreamcast, PC, playstation 1, Virtual Boy, Snes
Programming Language of Choice: c++
Contact:

Re: Define multidimensional array in a object

Post 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?
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Define multidimensional array in a object

Post 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.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Define multidimensional array in a object

Post 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
User avatar
ultimatedragoon69
Chaos Rift Regular
Chaos Rift Regular
Posts: 122
Joined: Tue Oct 28, 2008 1:57 pm
Current Project: Pangea's quest (text ~tile~ based rpg)
Favorite Gaming Platforms: Dreamcast, PC, playstation 1, Virtual Boy, Snes
Programming Language of Choice: c++
Contact:

Re: Define multidimensional array in a object

Post 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:
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: Define multidimensional array in a object

Post 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.
User avatar
mv2112
Chaos Rift Junior
Chaos Rift Junior
Posts: 240
Joined: Sat Feb 20, 2010 4:15 am
Current Project: Java Tower Defence Game
Favorite Gaming Platforms: N64/Xbox 360/PC/GameCube
Programming Language of Choice: C/++, Java
Location: /usr/home/mv2112
Contact:

Re: Define multidimensional array in a object

Post 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");
}

User avatar
Zer0XoL
ES Beta Backer
ES Beta Backer
Posts: 54
Joined: Fri Apr 24, 2009 1:18 pm
Current Project: Zelda untitled multiplayer game
Favorite Gaming Platforms: PC, GBA, N64
Programming Language of Choice: C++, Lua
Location: Sweden
Contact:

Re: Define multidimensional array in a object

Post 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
{
}
Image
Im Blue
Post Reply