I have a problem when I try to pass the pointer of an array (which contains parameters needed by some functions in my program) to a structure, which then should be passed to those functions. GSL for example wants me to pass parameters in this way.
A little example program looks like this:
#include <iostream>
using namespace std;
struct myparams
{
double * a;
double ** b;
};
int main()
{
double c[10] = {0,1,2,3,4,5,6,7,8,9};
double d[4][3] = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
double** e = new double*[4];
for (int i = 0; i < 4; i++) {
e[i] = new double[3];
}
myparams params;
// THIS WORKS:
params.a = c;
for (int i = 0; i < 10; i++) {
cout << params.a[i] << endl;
}
// THIS DOESN'T WORK
params.b = d;
// THIS WORKS:
params.b = e;
delete[] e;
}
What is the problem with
params.b = d
The Compiler complains with "cannot convert 'double[4][3]' to 'double**' in assignment"
or something like that (translated from german).
C. In this program, we have a pointer ptr that points to the 0th element of the array. Similarly, we can also declare a pointer that can point to whole array instead of only one element of the array. This pointer is useful when talking about multidimensional arrays.
A whole array cannot be passed as an argument to a function in C++. You can, however, pass a pointer to an array without an index by specifying the array's name. In C, when we pass an array to a function say fun(), it is always treated as a pointer by fun().
double d[4][3];
is an array of arrays. double b**;
is a pointer to pointer. These types are not the same (the common "arrays are just pointers" you might have read on the internet is wrong).
Elements of d
are of type double[3]
. Arrays, when passed around, decay to pointers to their first element (see section 4.2. of C++ standard). d
will decay to double(*)[3]
(a pointer to array of 3 doubles).
Long story short, double(*)[3]
is not convertible to double**
and this is what compiler is telling you.
If you need to keep d
as it is, you need to declare b as double (*b)[3]
;
For more in-depth explanation, refer to this SO question.
It's because a pointer to a pointer (or an array of pointers as it can be used as) is not the same as an array of arrays. The layout in memory is incompatible.
For example, lets say we have these two declarations:
char aa[2][2] = { { 'a', 'b' }, { 'c', 'd' } };
char **pp;
pp = new char*[2];
pp[0] = new char[2];
pp[1] = new char[2];
The array aa
looks like this in memory:
+----------+----------+----------+----------+
| aa[0][0] | aa[0][1] | aa[1][0] | aa[1][1] |
+----------+----------+----------+----------+
The "array" pp
meanwhile looks like this:
+------+------+
| a[0] | a[1] |
+------+------+
| |
| v
| +---------+---------+
| | a[0][0] | a[0][1] |
| +---------+---------+
V
+---------+---------+
| a[0][0] | a[0][1] |
+---------+---------+
The "array" pp
contains pointers to another "array"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With