Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass the pointer of a static 2D array to a structure/class?

Tags:

c++

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).

like image 729
GriffinPeterson Avatar asked Feb 15 '13 14:02

GriffinPeterson


People also ask

How we can point pointer to 2D array?

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.

Can you pass an array by pointers?

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().


2 Answers

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.

like image 134
jrok Avatar answered Nov 07 '22 05:11

jrok


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"

like image 24
Some programmer dude Avatar answered Nov 07 '22 06:11

Some programmer dude