0

As a part of my homework I have to make a function which gets a dynamic matrix and finds the matrix's elements which is equal to the sum of it's (i+j), also it have to return by value the array's size and return by reference the array. Actually I have finished with the size part and all the function, what I dont get it how can I send from main to the function an arr of struct (cuz its not initialized yet), and how can I update it in the function.

Thanks!

typedef struct Three { // struct for the elements
    int i;
    int j;
    int value;
}Three;

typedef struct List {   // linked list struct
    Three node;
    struct List *next;
}List;

Three CreateThree(int i, int j, int value);
List *CreateThreeList(int **Mat, int rows, int cols);
Three *CreateThreeArr(int **Mat, int rows, int cols, int *newsize);
int CreateArrAndList(int **Mat, int rows, int cols);

void main() {
    int **mat;
    int row, col, i, j, value, arr_size;

    printf("Please select the number of Rows and Cols in Matrix :\n");
    printf("Rows: ");
    scanf("%d", &row);
    printf("Columns: ");
    scanf("%d", &col);

    mat = (int**)malloc(row * sizeof(int));
    for (i = 0; i<col; i++)
        mat[i] = (int*)malloc(col * sizeof(int));
    printf("Please select %d values to your matrix:\n", row*col);
    for (i = 0; i<row; i++)
    {
        for (j = 0; j<col; j++)
        {
            printf("select value for [%d][%d]: ", i, j);
            scanf("%d", &value);
            mat[i][j] = value;
        }
    }
    arr_size = CreateArrAndList(mat, row, col);
}

Three CreateThree(int i, int j, int value) {    
    Three node;
    node.i = i;
    node.j = j;
    node.value = value;
    return node;
}

List *CreateThreeList(int **Mat, int rows, int cols) {
    int i, j;
    List *lst = NULL; 
    List *currLst = lst;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if ((i + j) == Mat[i][j]) {
                List *tmp = (List*)malloc(sizeof(List));
                tmp->node = CreateThree(i, j, Mat[i][j]); 
                tmp->next = NULL;
                if (currLst == NULL) {
                    lst = tmp;
                }
                else {
                    currLst->next = tmp;
                }
                currLst = tmp;
            }
        }
    }
    return lst; 
}

Three *CreateThreeArr(int **Mat, int rows, int cols, int *newsize) {
    int i, j, arrIndex = 0, size = 0;
    Three *arr; 
    arr = (Three*)malloc((rows*cols) * sizeof(Three));
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if ((i + j) == Mat[i][j]) { 
                arr[arrIndex++] = CreateThree(i, j, Mat[i][j]); 
                size++; 
            }
        }
    }
    arr = (Three*)realloc(arr,size * sizeof(Three));
    *newsize = size; 
    return arr; 
}

int CreateArrAndList(int **Mat, int rows, int cols) {
    int arrSize;
    Three *arr = CreateThreeArr(Mat, rows, cols, &arrSize);
    List *lst = CreateThreeList(Mat, rows, cols);
    return arrSize;
}
R_L
  • 33
  • 1
  • 8
  • Never cast the result of `malloc`: https://stackoverflow.com/q/605845/6872717 – alx - recommends codidact May 13 '19 at 16:53
  • This: `arr = (Three*)malloc((rows*cols) * sizeof(Three));` should be rewritten as: `arr = malloc(sizeof(*arr) * rows * cols);`. 1) Don't cast malloc. 2) sizeof is preferably applied to a variable and not to a type, so that if you change the type, you don't have to care about every sizeof appearance. 3) `(rows * cols)` could overflow before being multiplied by sizeof. As sizeof returns `size_t` you will avoid overflow (if it still overflows, you have a serious problem :)) – alx - recommends codidact May 13 '19 at 17:00
  • `main` should be defined as `int main(void)` – alx - recommends codidact May 13 '19 at 17:05

1 Answers1

0
ptrdiff_t create_arr_and_list(int **mat, ptrdiff_t rows, ptrdiff_t cols, struct three **arr, struct list **lst)
{
        ptrdiff_t nmemb;

        *arr = create_three_arr(mat, rows, cols, &nmemb);
        *lst = create_three_list(mat, rows, cols);

        return nmemb;
}

You can create a pointer in main (struct three *arr;, and struct list *lst;), pass a pointer to a those pointers (create_arr_and_list(mat, rows, cold, &arr, &lst);), and you initialize them later in the function.

int main(void)
{
        int **mat;
        int value
        ptrdiff_t row, col, nmemb;
        struct three *arr;
        struct list *lst;

        printf("Please select the number of Rows and Cols in Matrix :\n");
        printf("Rows: ");
        scanf("%ti", &row);
        printf("Columns: ");
        scanf("%ti", &col);

        mat = malloc(sizeof(*mat) * row);
        for (i = 0; i < col; i++)
                mat[i] = malloc(sizeof(*mat[i]) * col);

        printf("Please select %ti values to your matrix:\n", row * col);

        for (ptrdiff_t i = 0; i < row; i++) {
                for (ptrdiff_t j = 0; j < col; j++) {
                        printf("select value for [%ti][%ti]: ", i, j);
                        scanf("%d", &value);
                        mat[i][j] = value;
                }
        }
        nmemb = create_arr_and_list(mat, rows, cold, &arr, &lst);
}
  • When I try your code, It's not updating arr in main, I dont get the reason for that, because what I did in the function is finalarr(which is the arr in main) = arr; and same for the list, Its not updating the pointer to pointer in main – R_L May 13 '19 at 18:19
  • @R_L Edit your question, adding the updated code (don't overwrite the old code, append it at the end), and we'll try to see any problems there :) – alx - recommends codidact May 13 '19 at 20:24