0

I have a code which is programmed in static memory (functions which receive static 2D array) (static code will not compile, 2D array have not dimension) and I need to translate it to dynamic memory with pointers (functions which receive pointers).

The static memory code is:

void mas_corto(unsigned int c[][], unsigned int a[][], int P[][], unsigned int nNodos)
{
int i,j,k;
for (i = 0; i < nNodos; i++){
    for(j=0; j < nNodos; j++){
        // Inicializamos con el coste de los caminos directos
        A[i][j] = C[i][j]; P[i][j] = -1;
    }
}
for (k = 0; k < nNodos; k++)
    for (i = 0; i < nNodos; i++)
        for (j=0; j< nNodos; j++)
            if (A[i][k]+A[k][j] < A[i][j])
            {
                A[i][j] = A[i][k] + A[k][j];
                P[i][j] = k;
            }
}

void camino (int P[][], int i, int j)
{
int k;
if ((k=P[i][j])== -1)
    return;
camino(i,k);
printf("%d",k);
camino(k,j);
}

#define boolean int
void warshall (boolean c[][], boolean a[][], unsigned int nNodos)
{
int i,j,k;
for (i = 0; i < nNodos; i++)
    for (j=0; j< nNodos; j++)
        A[i][j] = C[i][j];
    for (k = 0; k < nNodos; k++)
        for (i = 0; i < nNodos; i++)
            for (j=0; j< nNodos; j++)
                A[i][j] = A[i][j] || A[i][k] && A[k][j];
}

As you can see, functions receive static 2D static array, and I need convert them into 2D pointers like:

void mas_corto(unsigned int **C, unsigned int **A, int **P, unsigned int nNodos)
{
    // CODE TRANSLATED
}

void camino (int **P, int i, int j)
{
    // CODE TRANSLATED
}

#define boolean int
void warshall (boolean **C, boolean **A, unsigned int nNodos)
{
    // CODE TRANSLATED
}

But I do not know how can I translate the code containted inside static function to pointer functions. Any idea how can I achieve that? (I need translate/adpat static in-function code to pointers, in other words, I need fill where // CODE TRANSLATED appear)

Thank you.

JuMoGar
  • 1,740
  • 2
  • 19
  • 46
  • 1
    The static code shown does not compile. You can't use `[][]` in the parameter list. – Jonathan Leffler May 22 '18 at 13:44
  • 1
    Your "static" code is invalid, and should not build. And without knowing exactly what you are passing to the functions, an array of arrays is *not* the same as a pointer to pointer. The memory layout is completely different, as explained in [this old answer of mine](https://stackoverflow.com/questions/18440205/casting-void-to-2d-array-of-int-c/18440456#18440456). Better try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us. – Some programmer dude May 22 '18 at 13:44
  • @JonathanLeffler Yes, I know, due to that (I do not know 2D length array) I must convert it into pointers – JuMoGar May 22 '18 at 13:48
  • Thank you both. I have just updated question. – JuMoGar May 22 '18 at 13:50
  • Note that `boolean array[DIM1][DIM2]` cannot be passed to a function that takes `boolean **ptr_to_prt`. If you write the 'static' code properly, and if you are using a compiler for the current millennium rather than the previous one, then you can use the VLA notation to pass any size of array to the function(s). For example, `void mas_corto(unsigned int c[][], unsigned int a[][], int P[][], unsigned int nNodos)` becomes `void mas_corto(unsigned int nNodos, unsigned int c[][NNodos], unsigned int a[][nNodos], int P[][nNodos])` (and you can specify the size of the leading dimension too). – Jonathan Leffler May 22 '18 at 13:53
  • Are the arrays considered always rectangular or could they be [jagged arrays](https://en.wikipedia.org/wiki/Jagged_array) ? – dvhh May 22 '18 at 14:26
  • @dvhh They are jagged arrays. Distincts rows can have a number of columns distincts – JuMoGar May 22 '18 at 14:37
  • but with a guarantee that numColumn and numRows > nNodos ? – dvhh May 22 '18 at 14:39
  • @dvhh yes, number of rows/columns < nNodos – JuMoGar May 22 '18 at 14:43
  • then you could use `unsigned int **c` which is functionally equivalent to a 2d jagged array ( see for example argv ) – dvhh May 22 '18 at 14:47
  • @dvhh Yes, that was my initial idea, but I do not know how translate inside function code to work with **C, **A,... – JuMoGar May 22 '18 at 14:49
  • 1
    the access to the data would be the same as your current code `c[i][j]` – dvhh May 22 '18 at 14:52
  • @dvhh So... Only changing X[][] to **X should works equal? – JuMoGar May 22 '18 at 14:56
  • This is what I am saying, but you could try it for yourself before believing a stranger on the internet. – dvhh May 22 '18 at 15:00
  • @dvhh Jajaja, yes, of course, I will continue working on it – JuMoGar May 22 '18 at 15:02

1 Answers1

3

Actually you can use arrays since you do know the size and C supports variable-length arrays.

Just change the order of arguments a bit to put the size first, and you can use it in the remaining arguments:

void mas_corto(unsigned int nNodos, unsigned int c[][nNodos], unsigned int a[][nNodos], int P[][nNodos]) { ... }
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thank you for the advice. But it is a requisite, code must be translated to pointers. As you say me, it is a fix for static code, but it must be done with pointers and dynamic memory. – JuMoGar May 22 '18 at 13:56
  • 1
    Also please note that you are using VLAs which is not recommended at all. – Antonin GAVREL May 22 '18 at 14:02
  • @JuMoGar Then the problem is what you will pass to the functions. What do you mean with "pointers and dynamic allocation"? – Some programmer dude May 22 '18 at 14:02
  • 1
    @AntoninGavrel Why would that be? VLA's are an integral part of C since the C99 standard. – Some programmer dude May 22 '18 at 14:02
  • @JuMoGar This _is_ pointers. An array `int c[][nNodos]` when declared as a parameter to a function, decays into a pointer to the first element. In this case an array pointer `int (*c)[nNodos]` which can be used as `c[i][j]`. – Lundin May 22 '18 at 14:10
  • 2
    @AntoninGavrel The code isn't really using VLA:s, but pointers to VLA:s. You don't need to pass a VLA to the function for it to work, any array is fine. Modern C programming is done with pointers to VLA all the time - it is much more common than actual VLA instances. – Lundin May 22 '18 at 14:12
  • @Someprogrammerdude for using `void mas_corto(unsigned int nNodos, unsigned int c[][nNodos], unsigned int a[][nNodos], int P[][nNodos])` you need to have declared `nNodos`, but this is a number which I pass as parameter and I do not know what is its size, so I cant declare it – JuMoGar May 22 '18 at 14:17
  • In header I get an error dued to that, it is a parameter not defined neither can be defined (I do not know the lenght) – JuMoGar May 22 '18 at 14:18
  • @Someprogrammerdude VLA can cause a segfault when the stack run out of space which is dependent on the unbound parameters that are passed to the function – dvhh May 22 '18 at 14:19
  • @dvhh Yes, I get the error that nNodos is not declared – JuMoGar May 22 '18 at 14:23
  • @JuMoGar What compiler are you using? Which version of it? What flags (if any) do you pass to the compiler when building? – Some programmer dude May 22 '18 at 14:27
  • Compiler: GNU_GCC - MinGW; I do not know; No flags – JuMoGar May 22 '18 at 14:42