I have a dynamically allocated 2D array Volatility[r][c] with r rows and c columns in C++. Is it somehow possible to create a pointer ptrColumn to a certain column c1, such that I can access the element (r1,c1) with ptrColumn[r1]?
So far, I tried to create dynamic pointers. But I didn't manage to do it.
Thank you!
-
"dynamically allocated 2D array" is not a well-defined term in C++. There are at least 2 different ways to dynamically allocate a 2D array. You need to provide more information about the physical structure of your array in memory.AnT stands with Russia– AnT stands with Russia2016-07-25 20:15:35 +00:00Commented Jul 25, 2016 at 20:15
4 Answers
You need a stride iterator. The ++ operator for a normal pointer returns a new pointer with an offset 1; for a stride iterator, the ++ operator will return a new stride iterator with a physical offset c; And so for operator [], + and --; Here is a simple example:
template< typename Iterator_Type >
struct stride_iterator
{
typedef typename std::iterator_traits<Iterator_Type>::value_type value_type;
typedef typename std::iterator_traits<Iterator_Type>::reference reference;
typedef typename std::iterator_traits<Iterator_Type>::difference_type difference_type;
typedef typename std::iterator_traits<Iterator_Type>::pointer pointer;
typedef typename std::iterator_traits<Iterator_Type>::iterator_category iterator_category;
Iterator_Type iterator_;
difference_type step_;
stride_iterator( Iterator_Type it, difference_type dt ) : iterator_(it), step_(dt) {}
reference operator []( difference_type dt )
{ return iterator_[dt*step_]; }
//other ctors, dtor and operators
};
This case, suppose the pointer holding the 2D array is double** dat, and the dimension for the array is r by c, you can create a column iterator at column index c1 with
auto col_itor = stride_iterator<double*>{ dat + c1, c };
and access the element at dat[r1][c1] with operator []
auto& elem = col_itor[r1];
Comments
No, that's not possible. One alternative you have is to create another 2D array with a traspose of the original array but is just useless because you'd have to update this array every time original array changes. Perhaps there is other ways to do it but an array of columns just don't.
1 Comment
Usually the first dimention is for row index, and the second for column.
First you should allocate memory for array of pointers (e.g. int *) and save addres as pointer to pointers:
int** Volatility = new int * [r];
Then arrange loop to allocate memory for each row. E.g.:
for(int i = 0; i < r; i++)
Volatility[i] = new int [c];
But it is your desition how to work with indexes.
If you want to work with columns on first index, just change the logic:
int r = 5, c = 10;
int** Volatility = new int * [c];
// allocate memory for each column
for(int i = 0; i < c; i++)
{
Volatility[i] = new int [r];
}
As you see Volatility[col][row] is a single element, and Volatility[col] is a pointer to columt. But now you cannot work with pointer to row.
3 Comments
The easiest way, for me, is to reserve the block of memory:
double* array2d= new double[r*c];
then, you can calculate the pointers as array2d+index*r (remember, the block of memory stores the array column by column, from the first to the last column).
IF you want to calculate the pointers to rows, use array2d+index*r (in this case, the memory stores the array row after row.
If you want the pointers in some place to use double operator [][], you could use:
double **array= new double*[r];
for (int i=1; i<r; ++i)
array[i]= array[i-1]+c;
For this code, you could use array[i][j] in your code.