I figured it out, I had wrong capitalization of the function name.
Next question:
If I have a pointer to the first element of a dynamically allocated 2 dimension array, is there any way to use two subscripts with that pointer.
Code:
//I create a dynamically allocated array:
int i;
int N = 100;
double **A;
double *p;
A = new double *[N]
for(i = 0; i < N; i++) A[i] = new double [N];
// and point a pointer to the first element.
p = A[0];
//now I want to be able to use it like this:
p[3][4] = 12;
C really has no concept of multi-dimensional arrays; all arrays are really stored in a one-dimensional format in memory. When you want to access element [3][4], the compiler actually performs some math to get a one-dimensional index: 3 * (number of elemts in row) + 4. If the compiler doesn't know how many elements are in a row, it cannot do this.
So, if all you're given is a pointer to the first element of a multidimensional array, you are effectively screwed.
Your code creates an array of pointers, this is not a matrix.
In the matrix examples below, note that "double (*pmd)[5]" declares pmd to be a pointer to an array of 5 doubles,
as opposed to "double *pmd[5]" which is an array of 5 pointers to double; the parenthesis around *pmd is what makes the difference.
Using Microsoft compiler, all 3 examples produce essentially the same code:
allocate 160 bytes,
set [ptr+56] = [ptr + (((1 x 5) + 2) x sizeof(double))] to 1.0
free ptr.
Can you do this if you need both dimensions to be dynamically allocated?
Not with the Microsoft compilers. Only the first dimension of a muti-dimensional array is allowed to be dynamic, the rest have to be compile time constants. You would need to use a vector of pointers to accomplish the equivalent, and would have to iterate for each allocation and/or freeing of a vector. The entity would be a mix of pointers and doubles.
In the examples above, what I really created was a pointer to an vector of 5 doubles, such as "double (*pv)[5]". C and C++ allow pv[j] or (*pv+i)[j], effectively promoting the pointer to a vector to a pointer to a matrix.
For a more familiar example, "double *ps" is a pointer to a scalar double (just one instance), and C and C++ allow ps or *(ps+i), effectively promoting the pointer to a scalar to a pointer to a vector.
Here is an example that actually uses a pointer to a matrix:
Not with the Microsoft compilers. Only the first dimension of a muti-dimensional array is allowed to be dynamic, the rest have to be compile time constants.
In the examples above, what I really created was a pointer to an vector of 5 doubles, such as "double (*pv)[5]". C and C++ allow pv[j] or *(pv+i)[j], effectively promoting the pointer to a vector to a pointer to a matrix.
As an analogy, "double *ps" is a pointer to a scalar double (just one instance), and C and C++ allow ps or *(ps+i), effectively promoting the pointer to a scalar to a pointer to a vector.
Here is an example that actually uses a pointer to a matrix:
My code from post 3 works to create a two dimensional dynamically allocated array. Try it. I don't understand why you tell me that it doesn't work.
Code:
//next two lines create a dynamically allocated N by M array A[N][M]
double **A = new double *[N];
for(i = 0; i < N; i++) A[i] = new double[M];
//we can then use it like this
A[1][3] = 14;
cout << A[1][3];
What I was asking was not how to create the array (though if there is a better way, I'd be glad to hear it, this method always seemed inelegant to me), but if I later have a pointer pointing to the first element of the array, how to use it with two subscripts.
Code:
//make a pointer and point it to the first element of A
double *p;
p = A[0];
//I wanted to be able to use p something like p[1][3]
//you gave me the answer by typecasting the pointer
((double (*)[M])p)[1][3] = 14;
cout << ((double (*)[M])p)[1][3];
You are talking past one another, thanks to how C (and C++) treats multi-dimensional and ragged arrays. Jeff Reid is creating multi-dimensional arrays while NeoDevin is creating ragged arrays. A multi-dimensional array occupies a monolithic block of memory and is allocated by a single new/malloc, while a ragged array comprises multiple chunks of memory and requires multiple new/malloc invocations. Both are accessed the same way: [noparse]multi_dim_array[index1][index2][/noparse] versus [noparse]ragged_array[index1][index2][/noparse].
If I have a pointer pointing to the first element of the array, how to use it with two subscripts.
You can't. You need a pointer to one of the pointers in A in order to use two subscripts. If you just copy the first pointer in A to a pointer to double, "p = A[0]", there's no way to get to A[1], A[2], ..., from p, because the vector of pointers only exists in A, while p only contains a single pointer. You'd have to create a duplicate of A, a pointer to a pointer to a double. You can implement this with just two allocated chunks of memory, by allocating a large vector, then setting A[] to sequentially higher locations in the large vector:
Code:
int main()
{
int i0, i1; // indexes
int d0, d1; // dimension sizes
d0 = 4;
d1 = 5;
double **apd = new double *[d0]; // allocate vector of pointers
double *pd = new double[d0*d1]; // allocate large vector of doubles
double *pt = pd; // temp pointer to vector of doubles
for(i0 = 0; i0 < d0; i0++){ // set pointers to vectors of doubles
apd[i0] = pt;
pt += d1;}
double **ppd = apd; // copy of apd;
for(i0 = 0; i0 < d0; i0++) // access the data
for(i1 = 0; i1 < d1; i1++)
ppd[i0][i1] = 1.0*i0*i1;
delete [] pd; // delete large vector of doubles
delete [] apd; // delete vector of pointers
return(0);
}
D H said:
You are talking past one another, thanks to how C (and C++) treats multi-dimensional and ragged arrays. Jeff Reid is creating multi-dimensional arrays while NeoDevin is creating ragged arrays.
I already mentioned this in post #6: "Your code creates an array of pointers, this is not a matrix."