0

I have a 2D array in the function arrayConstruction and I want to give it to the main function to use it there, it works but the values retrieved there are totally inconsistent. Bellow is what I tried to do so:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h> 
#include <unistd.h>
#include <ctype.h>


void arrayConstruction(int nb_row, char** result, int (*givenArr)[2]){

    const char * separator = " ";
    char * strToken;
    char *outt;
    char *end;

    /* 1D array */
    int arrBuf[nb_row*2];
    /* 2D array */
    int (*myArr)[2] = (int(*)[2])arrBuf;
    int i;
    outt = strdup(*result);
    /* Store numbers as 1D array */
    strToken = strtok ( outt, separator );
    for (i = 0; i < nb_row*2 && strToken != NULL ; i++) {
        arrBuf[i] = (int)strtol(strToken, &end, 10);
        strToken = strtok ( NULL, separator);
    }

    givenArr = myArr;


}



int main(int argc, char **argv) 

{

char *result = 
" 2 1\n\
  3 2\n\
  5 2\n\
  5 4\n\
  6 1\n\
  6 2\n\
  7 1\n\
  7 3\n\
  7 4\n\
  8 1\n\
";


int nb_rows = 10;
int emptyArr[][2] ={0};
arrayConstruction(nb_rows, &result, emptyArr);


int i;
  for (i = 0; i < nb_rows; i++) {
    printf("%d---%d\n", emptyArr[i][0], emptyArr[i][1]);
}

}

I tried to access it creating a pointer to the array but it's not the right values.

ADL92
  • 1
  • 3

1 Answers1

0

The line

givenArr = myArr;

in the function arrayConstruction will only change the value of the local variable givenArr, which is a pointer. It will not change the original array emptyArr in any way, so that the function main has no access to the new value.

Even if the function main did somehow get access to the new value, this value would be useless to main, because the value is a dangling pointer, for the following reason:

The expression myArr is a pointer to the first element of the array arrBuf, i.e. &arrBuf[0]. However, the entire array arrBuf will cease to exist as soon as the function arrayConstruction returns, because it is a local array with automatic lifetime. Therefore, as soon as the function returns, the pointer will point to a non-existant object, so the pointer is useless.

For this reason, it does not make sense to store the data in an array that is local to the function arrayConstruction. It is more meaningful for the array to be declared inside the function main, so that its lifetime is as long as the function main.

In your function main, you are using a 2D array, but in the function arrayConstruction, you are using both a 2D array and a 1D array. Since attempting to access a 2D array as a 1D array is not allowed in plain ISO C (although it works on most platforms), it would be better to decide whether you want to use a 2D array or a 1D array, and be consistent in your entire program.

Here is a working example which uses a 1D array:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void arrayConstruction( int *nb_elements, int givenArr[], char *input )
{
    const char * separator = " ";
    char * strToken;
    char *outt;
    int i;

    outt = strdup( input );

    strToken = strtok ( outt, separator );

    for ( i = 0; i < *nb_elements && strToken != NULL; i++ )
    {
        givenArr[i] = strtol( strToken, NULL, 10 );
        strToken = strtok ( NULL, separator);
    }

    free( outt );

    *nb_elements = i;
}

int main( void )
{
    char *input =
        " 2 1\n"
        " 3 2\n"
        " 5 2\n"
        " 5 4\n"
        " 6 1\n"
        " 6 2\n"
        " 7 1\n"
        " 7 3\n"
        " 7 4\n"
        " 8 1\n"
    ;

    int arr[20] = {0};
    int nb_elements = sizeof arr / sizeof *arr;
    arrayConstruction( &nb_elements, arr, input );

    for ( int i = 0; i < nb_elements / 2; i++ )
    {
        printf( "%d---%d\n", arr[i*2+0], arr[i*2+1] );
    }
}

Please note that I am calling free after using strdup, which you did not do in your code, which caused a memory leak.

This program has the following output:

2---1
3---2
5---2
5---4
6---1
6---2
7---1
7---3
7---4
8---1

Here is a working example which uses a 2D array:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void arrayConstruction( int *nb_rows, int givenArr[][2], char *input )
{
    const char * separator = " ";
    char * strToken;
    char *outt;
    int i;

    outt = strdup( input );

    strToken = strtok ( outt, separator );

    for ( i = 0; i < *nb_rows && strToken != NULL; i++ )
    {
        for ( int j = 0; j < 2 && strToken != NULL; j++ )
        {
            givenArr[i][j] = strtol( strToken, NULL, 10 );
            strToken = strtok( NULL, separator);
        }
    }

    free( outt );

    *nb_rows = i;
}

int main( void )
{
    char *input =
        " 2 1\n"
        " 3 2\n"
        " 5 2\n"
        " 5 4\n"
        " 6 1\n"
        " 6 2\n"
        " 7 1\n"
        " 7 3\n"
        " 7 4\n"
        " 8 1\n"
    ;

    int arr[10][2] = {0};
    int nb_rows = sizeof arr / sizeof *arr;
    arrayConstruction( &nb_rows, arr, input );

    for ( int i = 0; i < nb_rows; i++ )
    {
        printf( "%d---%d\n", arr[i][0], arr[i][1] );
    }
}

This program has the same output as the other one.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • Thanks a lot for the explanations. Is there a way to reproduce that with a 2D array ? I ask because another function in my program is waiting for _arr_ to be a 2D array – ADL92 Nov 13 '22 at 19:47
  • This function I am talking about, has as parameter a **int arr[][2]** – ADL92 Nov 13 '22 at 19:48
  • @ADL92: I have now added a second solution which uses a 2D array everywhere. – Andreas Wenzel Nov 13 '22 at 20:16