dynamically allocating a 2D array in a class

Started by
13 comments, last by Zahlman 19 years, 3 months ago
I'm writing a class to easily load bitmaps. Because of this I want to allocate an array the size of which depends on the size of the bitmap I want to load (like this: array[sizeofimage][3] - assuming I'm using an RGB bitmap). anyway, here's a proof of concept (console app) to explain things better. I allocate a 2D array(array[size][3]) and try to fill the array[][1] part with 1's, which I then try to read.

#include <iostream>
using namespace std;

class test
{
public:
	int *p;

	void allocate(int amount)
	{
		int (*p)[3] = new int[amount][3];
	}

	test(int amount)
	{
		allocate(amount);
	}
};

int main()
{
	int number;
	cin >> number;

	test test1(number);
	
	for(int i = 0; i < number; i++)
		test1.p[1] = 1;

	for(int j = -1; j < number+1; j++)
		cout << test1.p[j][1] << endl;

	return 0;
}
unfortunately this returns 3 errors:
Quote: test.cpp(28) : error C2109: subscript requires array or pointer type test.cpp(28) : error C2106: '=' : left operand must be l-value test.cpp(31) : error C2109: subscript requires array or pointer type
the 2D array isn't being recognized as being a 2D array it seems. anyone got a solution for this?
"It's better to regret something you've done than to regret something you haven't done."
Advertisement
Quote:Original post by Shai

anyone got a solution for this?


I think so...

Essentially, I find it better to use one dimensional arrays and then use little functions or macros to index them as if they were 2d.

So, make it like this:

#include <iostream>using namespace std;class test{public:	int *p;	void allocate(int amount)	{		p = new int[amount*3];	}	test(int amount)	{		allocate(amount);	}};int main(){	int number;	cin >> number;	test test1(number);	for(int i = 0; i < number; i++)		(test1.p)[(3*i)+1] = 1;	for(int j = -1; j < number+1; j++)		cout << test1.p[(j*3)+1] << endl;	return 0;}
[size="1"]
You are leaking memory.

int (*p)[3] = new int[amount][3];

Declares a new pointer called p to int[3], it does not use the p inside the class, which is an int*.

The correct method would be to use

class test{int (*p)[3];void allocate(int amount){	p = new int[amount][3];}..};
*does happy dance* :)
"It's better to regret something you've done than to regret something you haven't done."
Neither C nor C++ really support multidimensional arrays. You can either allocate a 'normal' 1D array and index it manually, or create an array of arrays. Furthermore, a pointer is always seen as a unidimensional array, so with int *p; you can never write p[a].

All things considered, you really just should use a std::vector<int> and write vec[x+y*row_size] instead of vec[y][x].

Or use boost::multi_array.

Edit: Jingo, your code is an utter abomination.
p[0] = new int[amount];p[1] = new int[amount];p[2] = new int[amount];

would be correct, but even then, would result on a 3xN array of arrays, not a Nx3 bidimensional array.

And of course, if you ever call allocate() twice... you'll still leak memory.

[Edited by - Fruny on January 1, 2005 1:17:15 PM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
i agree with Frunny. Rather then deal with trying to hack my way to getting a dynamic 2d array i just have a class that contains a 1d array but you access it, modify it and resize it just like a 2d array so that way you have the orginization of a 2d and the flexablity of a 1d

also

p[0] = new int[amount];
p[1] = new int[amount];
p[2] = new int[amount];

this will create array filled with garbage so you would have to go through and zero out each segment if your not sure if your going to use all of the array otherwise you could get some wierd results

reason: new calls the int constructor in that case witch dosnt exist so it just fills it with meaning-less garabage (numbers like 1820043882)

____________________________"This just in, 9 out of 10 americans agree that 1 out of 10 americans will disagree with the other 9"- Colin Mochrie
Quote:Original post by Fruny

Edit: Jingo, your code is an great utter abomination.


Thanks! :)
Edit by Fruny: You're welcome.

You cut half of my post off Fruny! tut tut

other half:

Plus the code is not really a hack in any shape or form. It is even used as an example in the standard, 5.3.4.5 if you are interested. :)
Edit by Fruny: Fine, I retract my objection.
#include <iostream>#include <vector>template<class T>class Array2D{   size_t m_rows;   size_t m_cols;   std::vector<T> m_data;public:   Array2D(size_t rows, size_t cols)   : m_rows(rows), m_cols(cols), m_data(rows*cols)   {}   T* operator[](size_t idx)             { return &m_data[idx*m_cols]; }   const T* operator[](size_t idx) const { return &m_data[idx*m_cols]; }};int main(){   int number;   cin >> number;   Array2D<int> test1(number, 3);   for(int i = 0; i < number; i++)      test1[1] = 1;   for(int j = -1; j < number+1; j++)      std::cout << test1[j][1] << std::endl;   return 0;}
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
int j = -1;

??
Hey, I don't pretend to understand what he's trying to do. [wink]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

This topic is closed to new replies.

Advertisement