1

I am trying to return a two-dimensional array from a function, but something goes wrong. arr2 on the main function is getting an error,

CXX0030: Error: expression cannot be evaluated

Code

int** file2array(char* filename) {

    FILE *fp = NULL;
    char c;
    int i = 0;
    int arr[9][9];

    if ((fp = fopen(filename, "r")) == NULL)
    {
        printf("File could not be opened\n");
    }
    else
    {
        while (!feof(fp))
        {
            c = fgetc(fp);

            if (c == '.') {
                arr[i/9][i%9] = 0;
                i++;
            }

            if (c>= '1' && c<='9') {
                arr[i/9][i%9] = c - 48;
                i++;
            }
        }
        fclose (fp);
    }

    return arr;
}

int main(){
    int** arr2 = file2array("SolverInput.txt");
}

2 Answers 2

1

A 2D array int arr[9][9] and a pointer to pointer int **arr are not interchangeable, use a pointer to an array int (*arr2)[9]:

void *file2array(char* filename){
    ...
    int arr[9][9];
    ...
    return arr;
}

int (*arr2)[9] = file2array("SolverInput.txt");

But note that arr is a local variable (his lifetime ends whith the function), use malloc:

void *file2array(char* filename){
    ...
    int (*arr)[9] = malloc(sizeof *arr * 9);
    ...
    return arr;
}

int (*arr2)[9] = file2array("SolverInput.txt");
...
free(arr2);

If you don't know the number of elements before-hand (an arbitrary number instead of 9) you can use a variable-length-array (VLA)

void *file2array(char* filename, int dim){
    ...
    int (*arr)[dim] = malloc(sizeof *arr * dim);
    ...
    return arr;
}

int dim = 9;
int (*arr2)[dim] = file2array("SolverInput.txt", dim);
...
free(arr2);

Also, fgetc() returns an int (not a char)

Change

char c;

to

int c;
Sign up to request clarification or add additional context in comments.

2 Comments

first of all, thanks a lot second, should i free only arr2 or should i free each and every index?
Only arr2, contents are in the same block, the rules are: if you call malloc n times you must call free n times too. You are welcome ;)
0

Arrays behave weirdly when then are passed as function parameters. That's how it is in C. Just don't do it.

Instead, you should embed the array in a struct.

typedef struct {
    int cell[9][9];
} sudoku;

You can then pass a sudoku * instead of an int ** to the function. This has the immediate benefit of telling the reader of your code what it does. An int ** can mean pretty much anything, but a sudoku * cannot.

int read_sudoku(const char *filename, sudoku *sud) {

    if (some error happens)
        return -1;

    sud->cell[3][8] = 5;
    return 0;
}

int main() {
    sudoku sud;

    if (read_sudoku("sudoku001.txt", &sud) == -1) {
        fprintf(stderr, "cannot read sudoku\n");
        return EXIT_FAILURE;
    }

    ...
}

This is the simplest it can get. No malloc, no free, just some code that does the actual work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.