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

前端 未结 9 1392
心在旅途
心在旅途 2020-12-29 02:37

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(doub         


        
相关标签:
9条回答
  • 2020-12-29 02:48

    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} }
    
    0 讨论(0)
  • 2020-12-29 02:51

    Another difference is that you can not make double to point to any other memory address if you declare it as double[][] ( Something like final field )

    But if you declare it as **double, then it can point to any memory location.

    0 讨论(0)
  • 2020-12-29 02:53

    No it is not. double[n][m] allocates a single block of memory big enough for your two dimensional array. You then get the convenience of not having to calculate your own indexing. When passing a two dimensional array to a function, the compiler requires you to give the size of the inner dimension so that it can work out the indexing.

    double** is a pointer to a pointer. Since C allows pointer arithmetic, it may mean an array of pointers, where each pointer points iself to an array of doubles. The values themselves need not reside in a contiguous block of memory. As you can see they are quite different beasts.

    If you have a double[n][m] and want to pass it to a double ** you will need to construct your own indexing array.

    0 讨论(0)
  • 2020-12-29 02:54

    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.

    0 讨论(0)
  • 2020-12-29 03:02

    [][] is not equivalent to **; double ** var; is a pointer of pointers and as you can see from your allocation in memory you hold an array of pointers and each pointer inside points to an array of values of double

    double var [4][4]; is held in memory in on place, and it is somewhat equivalent to double *; In this case the knows the size of the matrix ( 4 x 4 ) so when you use var[2][2], for example, it know where is that located in memory; var[x][y] translates to something like this: var[x + y * 4] and the declaration can be interpreted as double var [16];

    Raxvan.

    0 讨论(0)
  • 2020-12-29 03:05

    No... m1 is an array with four elements, each of which is an array of four elements. Same with m2. Even if the first "level" decays from an array into a pointer, the second "level" won't. The question is why? Let's look at some code:

    /* double[4][4] implicitly converts to double(*)[4]
     * giving you a pointer to first element of m1 so
     * you get back an array of four doubles.
     */
    double (*pm1a)[4] = m1[0];
    
    /* This isn't right, but let's pretend that it was
     * and that what you got back was a pointer
     * to a pointer that pointed to m1 properly.
     */
    double **pm1b = (double **)m1[0];
    

    So, what would happen with our hypothetical code if we were to do pm1a[1] and pm1b[1]?

    pm1a[1] is fine: it would correctly advance pm1a by 4 * sizeof(double) (since the pointer points to double[4]).

    pm1b[1], on the other hand, would break: it would advance by the wrong amount: the size of a pointer to a double.

    But this isn't all. There's a more subtle bug still. If both dimensions were to decay, the compiler could not know that an array is being accessed. It will happily interpret pm1b[1] as a pointer to a double. And then what happens? It will take whatever double value is stored at that location and treat it as a pointer to a double.

    You can see why this would be a disaster.

    0 讨论(0)
提交回复
热议问题