Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Isn't double[][] equivalent to **double?

I'm asking this because my program have two functions to multiply matrices, they multiply only 4x4 and 4x1 matrices. The headers are:

 double** mult4x1(double **m1, double **m2);
 double** mult4x4(double **m1, double **m2);

They do m1*m2 and return it in a **double, below is a snippet of 4x4 multiplication.

 double** mult4x4(double **m1, double **m2){
      double** result = (double**) malloc(sizeof(double)*4);
      for (int i = 0; i < 4; i++) {
           result[i] = (double*) malloc(sizeof(double)*4);
      }
      ...multiply...
      return result;
 }

The difference between mult4x1 and mult4x4 are only in the indexes used inside them.

I have these 3 matrices:

double m1[4][4] = {
    {2, 3, 5, 6},
    {9, 8, 1, 7},
    {5, 4, 3, 1},
    {7, 6, 1, 2}
};

double m2[4][4] = {
    {1, 0, 0, 0},
    {0, 1, 0, 0},
    {0, 0, 1, 0},
    {0, 0, 0, 1}
};

double m3[4][1] = {
    {2},
    {3},
    {3},
    {1}
};

Trying to multiply these matrices an error occurs.

double** test = mult4x4(m1, m2);
double** test2 = mult4x1(identity4x4(), m3);
//identity4x4() creates a 4x4 identity matrix - double** identity4x4();

Yields:

error: cannot convert double (*)[4]' todouble*' for argument 1' todouble* mult4x4(double*, double*)'

error: cannot convert double (*)[1]' todouble*' for argument 2' todouble* mult4x1(double*, double*)'

Isn't double[][] supposed to be equal to **double? An array of arrays of double. Any clarifications, misconceptions and errors are welcome.

like image 619
user1493813 Avatar asked Oct 28 '13 14:10

user1493813


People also ask

Is a double pointer a double array?

No. A multidimensional array is a single block of memory.

Is 2D array same as double pointer?

An array is treated as a pointer that points to the first element of the array. 2D array is NOT equivalent to a double pointer! 2D array is "equivalent" to a "pointer to row".

Can array index be a double?

In case it isn't clear, your array cannot be of double length. It's undefined behavior. This is because a double is not an integer, but a rational number that could be an integer.


4 Answers

No.
A double** is a pointer to a pointer to a double (double*).

So actually it should be created like this (note the extra * in the first malloc sizeof()):

  double** result = (double**) malloc(sizeof(double*)*4);   for (int i = 0; i < 4; i++) {        result[i] = (double*) malloc(sizeof(double)*4);   } 

So in memory it would look like this:

[] -> { d,d,d,d } [] -> { d,d,d,d } [] -> { d,d,d,d } [] -> { d,d,d,d } 

There are 4 buffers that hold 4 doubles, but are not continuous.

While your double[4][4] is a continuous buffer in memory, like this:

 { { d,d,d,d } { d,d,d,d } {d,d,d,d} {d,d,d,d} } 
like image 75
Yochai Timmer Avatar answered Sep 23 '22 12:09

Yochai Timmer


Although both double[N][M] and double** let you deal with 2D arrays, the two are definitely not equivalent: the former represents a 2D array of doubles, while the later represents a pointer to pointer to double, which can be interpreted (with the help of convenient square bracket syntax of C/C++) as an array of pointers to double, or as an array of arrays of double.

The double[N][M] represents 2D arrays of "rectangular" shape, while double** lets you build "free-form" (jagged) arrays by allocating different amounts of memory to each row of your matrix.

The difference to the compiler is that given double[N][M] and a pair of integers {r,c} it can compute the location of the element by computing the offset from the origin of the array, without reading anything from the memory. Given a double**, however, the compiler must compute the address of the pointer to a row, read that pointer, and only then compute the address of the target element. Because of this difference, the two are not interchangeable.

like image 45
Sergey Kalinichenko Avatar answered Sep 23 '22 12:09

Sergey Kalinichenko


There is no type [][]. What you have is in fact m2 which is an array of arrays of size 4 of type double and m1 which is an array of arrays of size 1. An array of arrays of size 4 is not equivalent to double pointer.

like image 36
Ivaylo Strandjev Avatar answered Sep 22 '22 12:09

Ivaylo Strandjev


Well I hope I will not turn out stupid here but the notation double [][] is also used when you are addressing a continuous block of memory, while double** is not necessarily continuous.

I think that is the reason behind the error. Even though you can use the same semantics to access values, they are actually different types.

like image 34
luk32 Avatar answered Sep 23 '22 12:09

luk32