There is something I still don't quite understand about the way matrices and other multidimensional arrays are represented in C and C+ and how to allocate them dynamically.
Consider the following code segment:
int main()
{
int n;
cin >> n;
int a[n][n];
...
}
If I understand correctly, this allocates an n by n matrix of integers on the stack. The (i,j)-th element of the matrix can be accessed using a[i][j]. The compiler automatically converts this into an access into the (n*i+j)-th element of a one dimensional array actually allocated.
Suppose now that I would like to allocate the n by n matrix a on the heap, instead of the stack. I can then do the following:
int main()
{
int n;
cin >> n;
int** a;
a = new int*[n];
for (int i=0;i<n;i++) a[i] = new int[n];
...
}
I can now access the (i,j)-th element again as a[i][j]. However, this is not exactly equivalent to the situation above as I actually had to allocate space for n*n int's, plus n pointers to int. Also, accessing a[i][j] now entails two accesses to memory instead of just one. On the other hand, the index computation n*i+j is avoided.
Suppose now that I am interested in n by m matrices where m is small, eg, m=2. Using the array of row pointers then wastes 33% of the space. Is there any way of avoiding that?
I can of course allocate a one-dimensional array and do the index arithmetic myself, but this does not seem to be the best solution to me.
Any information would be appreciated!
You could do
int *mat = new int[n*n];
then use mat[n*i+j]
Rather you would allocate one linear array of ints:
int main()
{
int n;
cin >> n;
int *a;
a = new int[n*n];
}
Doing the index math yourself is a good way to go.
You could reverse the allocation order. If you are concerned about 33% or whatever memory being taken up due to "row" pointers, why not just turn the rows into the columns and vice versa? Then, instead of [i][j]
you'd access an element with [j][i]
. Of course, this may or may not be practical in your situation, it's hard to say without more information.
But really, I see no problems using index maths, there's nothing inherently wrong with it.
You could create a class that did the index math for you, if that's where you're not liking things.
class Matrix
{
public:
Matrix(int iRows, int iCols)
: mRows(iRows), mCols(iCols), m(new int[mRows*mCols]) { }
~Matrix() { delete [] m; }
int &element(int iRow, int iCol) { return m[iRow * mCols + iCol]; }
int mRows, mCols, *m;
};
You can't do
int n;
cin >> n;
int a[n][n];
because the compiler needs to know exact size you will need on the stack during compile time. This is not possible when you are asking for it at run time :-) On the other hand you can do
#define N 10
int a[N][N];
In the other cases, you have to use dynamic allocation.
And allocation in C works just like that you allocate one piece of contiuous memory, indexes like a[i][j] are just syntactic sugar to jump into that memory, you can as well do *(a + k*i + j), where k is the size of the inner array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.