two dimensional array

S

Someonekicked

im trying to declare a two dimensional array using pointers. but it is not
working, any ideas?
 
O

osmium

Someonekicked said:
im trying to declare a two dimensional array using pointers. but it is not
working, any ideas?

Like this:

#include <iostream>
using namespace std;

//------------------
void test2(int b[][5])
{
cout << b[2][3] << endl;
}
//====================
int main()
{
int(*a)[5] = new int[3][5];
a[2][3] = 2048;
test2(a);
cin.get();
}
 
V

Val

| im trying to declare a two dimensional array using pointers. but it is not
| working, any ideas?
|

Programming is communicating in the first place.
1) Does the matrix know the rows and columns at compile time or run time only?
2) Why isn't working? Where is the code?
3) How did you express the Matrix? As a single array of row*col size, or as an array holding arrays?

See the C++ faq lite (google it) for your first hints.
 
A

Axter

Someonekicked said:
im trying to declare a two dimensional array using pointers. but it is not
working, any ideas?

There are many ways to create a two dimensional array in C++.

You can use a vector of vectors
std::vector<std::vector<int> > My2dOfInt;

You can also use a custom class, or you can use a pointers of pointers.

Check out the following link for examples, and for different methods.
http://www.tek-tips.com/faqs.cfm?fid=5575
 
A

Angad

I would say, the simplest way would be

int **p ;
p = new int *[ROWS] ;
for( int i = 0 ; i < ROWS ; i++ )
p = new int[COLUMNS];

But everyone seems to suggest vectors...
 
A

Axter

Angad said:
I would say, the simplest way would be

int **p ;
p = new int *[ROWS] ;
for( int i = 0 ; i < ROWS ; i++ )
p = new int[COLUMNS];

But everyone seems to suggest vectors...



You're missing the code to free the above allocated data.
Using **p (pointer of pointers) you need code for allocating the data,
code for keeping track of the sizes of the rows and columns and code to
deallocated the data.

So using **p is not the simplest approach.
It's far easier to use a vector that wraps all the logic behind a safe
container.
Your above code can be done in one line of code by using vectors.
vector<vector<int> > My2DArr(ROWS, std::vector<int>(COLUMNS));

IMHO, this one line of code is far simpler then the pointer of pointer
code, and the required tracking code, plus the required deallocation
code needed for the pointer of pointer method.
 
V

Val

| Your above code can be done in one line of code by using vectors.
| vector<vector<int> > My2DArr(ROWS, std::vector<int>(COLUMNS));

std::valarray for numbers.

Or single array acting as a Matrix:
int* Matrix = new int[ROWS*COLS];

But I think it's a nice excercise to do it the ** way :)
 
A

Angad

Yes, I agree that vectors simplify the matter a lot by reducing our
coding, but I must say that they add to a lot of unnecessary code to
the executable code. Compile time increases manyfold (I'm talking from
a personal experience). I'd say, use vectors only when basic data types
cannot be used....

As for the freeing of the memory, the code is:

for( int i = 0 ; i < ROWS ; i++ )
delete [] p ;
delete [] p ;

This code will definitely be faster than using vectors... (please
comment if I'm wrong)
 
V

Val

|
| This code will definitely be faster than using vectors... (please
| comment if I'm wrong)

You can't know in this stage. But the word "definetely" is a strong expression...
And once again, std::valarray is made for numbers. Very efficient. One needs to test thoroughly if a std::valarray implementation
needs to be replaced by an own version.
Much more can be said, but these are the big lines.
 
B

Bushido Hacks

Man, talk about conicidence. I was about to post a thread relating to
this topic.

I am interested in 2-D arrays. However, I'd like to do this task
without calling the vector class.

I would like to use pointers to declare a multidimensional array
without using the vector class. I can declare arrays and do addition,
transposition, and inversion. But what I'd like to know is how to
**MULTIPLY** two multidimensional arrays using C++ just using Dev
C++/GCC.
 
V

Val

| Man, talk about conicidence. I was about to post a thread relating to
| this topic.
|
| I am interested in 2-D arrays. However, I'd like to do this task
| without calling the vector class.
|
| I would like to use pointers to declare a multidimensional array
| without using the vector class. I can declare arrays and do addition,
| transposition, and inversion. But what I'd like to know is how to
| **MULTIPLY** two multidimensional arrays using C++ just using Dev
| C++/GCC.


First implement the 2d array. See the C++ faq on a nice hint.
When you succeeded, multiplication is going to be straightforward.
 
V

Val

|
| First implement the 2d array. See the C++ faq on a nice hint.
| When you succeeded, multiplication is going to be straightforward.

But right now you really should consider std::valarray :).
Unless it is your homework and you're not allowed to.
 
A

Axter

Angad said:
Yes, I agree that vectors simplify the matter a lot by reducing our
coding, but I must say that they add to a lot of unnecessary code to
the executable code. Compile time increases manyfold (I'm talking from
a personal experience). I'd say, use vectors only when basic data types
cannot be used....

As for the freeing of the memory, the code is:

for( int i = 0 ; i < ROWS ; i++ )
delete [] p ;
delete [] p ;

This code will definitely be faster than using vectors... (please
comment if I'm wrong)


More then likely there's not that much of a measurable difference
between the vector destructor, and the above code.
Even if there was, I would still prefer to use the vector which IMHO,
is a cleaner, and safer method.
Also, in general, a vector is more efficient at iterations then using a
pointer of pointers.
 
A

Angad

You're right, I tried out std:valarray - I can't compare to pointers,
but definitely faster than usual vectors...




And Val, don't mind me saying this, but looks like you're hell-bent on
convincing everyone about std:valarray... is it because it's got your
name in it ;)
 
V

Val

| You're right, I tried out std:valarray - I can't compare to pointers,
| but definitely faster than usual vectors...
|
|
|
|
| And Val, don't mind me saying this, but looks like you're hell-bent on
| convincing everyone about std:valarray... is it because it's got your
| name in it ;)

Good one :)

AS a matter of fact, right now I am in the very process of implementing many versions of matrices for testing purposes.
 
B

Bushido Hacks

It's not that I'm not allowed to use the vector class, I'm just not
interested in using vectors. I'm more comfortable with Arrays and
Pointers

I like Angad's method.

Here is what I'd really like to do with his codes:

class Matrix{
public:
Matrix(int rows = 4, int cols = 4){
setDims(rows,cols);
int **p ;
p = new int *[getRows()] ;
for( int i = 0 ; i < getRows() ; i++ ){
p = new int[getCols()];
};
};
Matrix &setDims(int rows,int cols){setRows(rows);setCols(cols);};
Matrix &setRows(int rows){this->rows = rows; return *this;};
Matrix &setCols(int cols){this->cols = cols; return *this;};
int getRows() const {return rows;};
int getCols() const {return cols;};
Matrix printMatrix() const {
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
cout << this[j] << " "; // I know this is incorrect, but I'm
just using it
// to illustrate the concept. Please correct if I am wrong.
};
cout << endl;
};
};
Matrix &setIdentity(){
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
this[j] = (i == j);
};
};
}; // Identity matrix
~Matrix(){
for( int i = 0 ; i < getRows() ; i++ ){
delete [] p ;
};
delete [] p ;
};
private:
int rows, cols;
};

// such that I can do this

int main(){
Matrix m(4,4); // yes I know I already declared defaults
// but I'm just using this as an example
m.setIdentity().printMatrix();
return 0;
};

The desired output should be

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
 
A

Axter

Bushido said:
It's not that I'm not allowed to use the vector class, I'm just not
interested in using vectors. I'm more comfortable with Arrays and
Pointers

I like Angad's method.

Here is what I'd really like to do with his codes:

class Matrix{
public:
Matrix(int rows = 4, int cols = 4){
setDims(rows,cols);
int **p ;
p = new int *[getRows()] ;
for( int i = 0 ; i < getRows() ; i++ ){
p = new int[getCols()];
};
};
Matrix &setDims(int rows,int cols){setRows(rows);setCols(cols);};
Matrix &setRows(int rows){this->rows = rows; return *this;};
Matrix &setCols(int cols){this->cols = cols; return *this;};
int getRows() const {return rows;};
int getCols() const {return cols;};
Matrix printMatrix() const {
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
cout << this[j] << " "; // I know this is incorrect, but I'm
just using it
// to illustrate the concept. Please correct if I am wrong.
};
cout << endl;
};
};
Matrix &setIdentity(){
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getCols(); j++){
this[j] = (i == j);
};
};
}; // Identity matrix
~Matrix(){
for( int i = 0 ; i < getRows() ; i++ ){
delete [] p ;
};
delete [] p ;
};
private:
int rows, cols;
};


I still recommend using a vector of vector over above method, but if
you still want to use above class, I recommend you change the
allocation and deallocation method to a more efficient method.
The above constructor and destructor call new and delete 1+Qty_Rows
You can use a more efficient method that calls new twice, and delete
twice.
You use one call to new that creates the array of pointers, and then
use a second call to new that creates the buffer for all required
rows*cols.
You then iterate through the pointers and have the point to different
sections of the buffer.
Here's a wrapper function that gives you an example of this method.

template < typename T >
T **Allocate2DArray( int nRows, int nCols)
{
T **ppi;
T *pool;
T *curPtr;
//(step 1) allocate memory for array of elements of column

ppi = new T*[nRows];

//(step 2) allocate memory for array of elements of each row
pool = new T [nRows * nCols];

// Now point the pointers in the right place
curPtr = pool;
for( int i = 0; i < nRows; i++)
{
*(ppi + i) = curPtr;
curPtr += nCols;
}
return ppi;
}

template < typename T >
void Free2DArray(T** Array)
{
delete [] *Array;
delete [] Array;
}

Furthermore, you could take this one step further, and use a method
that only calls new and delete one time.
See following wrapper class for 2 dimensional array.
http://code.axter.com/dynamic_2d_array.h

For more examples of different dynamic 2D array methods, see following
links:
http://www.tek-tips.com/faqs.cfm?fid=5575

http://code.axter.com/allocate2darray.h
http://code.axter.com/allocate2darray.c
 
B

Bushido Hacks

(skeptical) I don't know. That way seems to suck up more memory that
it should. Especially the lines where the pool is used.

One thing I certainly disagree with is the Free2DArray.
The problem with using
delete[] *Array;
is that it only deletes what ever is at Array[0]. Any other data in
in that row is still allocated. Thus, a memory leak is present at
Array[1], Array[2], etc.

That is why Angad's method is better. He added a for loop that
dealocates all the cells in each row.

Here is your method combined with his.

template<typename T>
void Free2DArray(T** m){
for(int i = 0; i < getRows(); i++){
delete [] *(m + i);
};
delete [] m;
};

I also noticed your way used much more memory that it should. Perhaps
this is why you prefere vectors over arrays.

In your Allocate2DArray, you created
T *pool = new T [nRows * nCols];
This statment says you want to allocate (nRows * nCols) space IN EACH
ROW!
You then renamed pool curPtr. This mean pool could drop all that
allocated space at the end of Allocate2DArray and could not put it back
in Free2DArray because you used the "new" operator.

Here's what I did to fix that

template < typename T >
T **Allocate2DArray(int rows = 4, int cols = 4){
setDims(rows,cols);
T **m = new T*[getRows()];
for( int i = 0; i < nRows; i++){
*(m + i) = new T[getCols()];
};
return m;
};

The use of the getRows() and getCols() functions, which calls the
private integer variables rows and cols seemed like a good idea
considering that getRows() will be needed in Free2DArray;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top