How to merge two matrices with pointers and dynamic memory allocation?

1

I wrote this code :

#include <stdio.h>
#include <malloc.h>
#define MAX(x,y) ((x > y) ? x : y)

int  MergeArray2D( int **retArrayPtr, int *retRowsPtr, int *retColsPtr,
                   int *leftArray, int leftRows, int leftCols,
                   int *rightArray, int rightRows, int rightCols )
{
    int  *retArray;
    int  i;
    int  j;
    int  retCols;
    int  retRows;

    if ((retArrayPtr == NULL) || (retColsPtr == NULL) || (retRowsPtr == NULL) || (leftArray == NULL))
        return (-1);

    retCols = leftCols + rightCols;
    retRows = MAX(leftRows, rightRows);

    retArray = calloc(sizeof(int), retRows * retCols);
    if (retArray == NULL)
        return (-2);

    /* First copy the left array into the merged array */
    for (i = 0; i < leftRows; i++) {
        for (j = 0; j < leftCols; j++) {
            retArray[i * retCols + j] = leftArray[i * leftCols + j];
        }
    }

    /* And then copy the right array into the merged array */
    for (i = 0; i < rightRows; i++) {
        for (j = 0; j < rightCols; j++) {
            retArray[i*retCols + j + leftCols] = rightArray[i * rightCols + j];
        }
    }

    *retArrayPtr = retArray;
    *retColsPtr = retCols;
    *retRowsPtr = retRows;

    return (0);
}

void  PrintArray2D( int **array, int numRows, int numCols )
{
    int  i;
    int  j;

    for (i = 0; i < numRows; i++) {
        for (j = 0; j < numCols; j++) {
            printf(" %d", array[i][j]);
        }
        printf("\n");
    }
}

int  main()
{
    int     leftRows;
    int     leftCols;
    int     **leftArray;
    int     rightRows;
    int     rightCols;
    int     **rightArray;
    int     i;
    int     j;
    int     count;
    int     result;
    int     *newArray;
    int     newRows;
    int     newCols;
    printf("sizeof(void *) = %d\n", sizeof(void *));
    printf("sizeof(int) = %d\n\n", sizeof(int));
    count = 0;

    printf("Matrix 1 -> ");
    scanf("%d%d", &leftRows, &leftCols);
    leftArray = calloc(sizeof(int **), leftRows);
    for (i = 0; i < leftRows; i++)
        *(leftArray+i) = calloc(sizeof(int *), leftCols);

    /* Initialize the left array */
    for (i = 0; i < leftRows; i++) {
        for (j = 0; j < leftCols; j++) {
            scanf("%d", &leftArray[i][j]);
        }
    }

    printf("Matrix 2 -> ");
    scanf("%d%d", &rightRows, &rightCols);
    rightArray = calloc(sizeof(int **), rightRows);
    for (i = 0; i < rightRows; i++)
        *(rightArray+i) = calloc(sizeof(int *), rightCols);

    /* Initialize the right array */
    for (i = 0; i < rightRows; i++) {
        for (j = 0; j < rightCols; j++) {
            scanf("%d", &rightArray[i][j]);
        }
    }

    /* Print out the left array */
    printf("Left Array:\n");
    PrintArray2D( leftArray, leftRows, leftCols);

    /* Print out the right array */
    printf("\nRight Array:\n");
    PrintArray2D( rightArray, rightRows, rightCols);

    /* Merge the two arrays */
    result = MergeArray2D(&newArray, &newRows, &newCols, *leftArray, leftRows, leftCols, *rightArray, rightRows, rightCols);
    if (result != 0) {
        printf("ERROR -- MergeArrays2D() returned %d\n", result);
    }

    /* Print out the merged array */
    printf("\nMerged Array:\n");
    PrintArray2D(&newArray, newRows, newCols);

    /* Clean up the allocated merged array when through using it */
    free(newArray);
}

However, it only prints the first row after merging both the matrices and none of the rows 1st index onwards. I think it has to do something with my calloc function and parameters passed while calling MergeArray2D. I have tried many changes since the past 3 days but nothing seems to work. Can you suugest me the required changes in the code please?

Here's the output from CLion :

sizeof(void *) = 4
sizeof(int) = 4

Matrix 1 ->2 2
1 2 3 4
 Matrix 2 ->2 2
4 5 6 7
 Left Array:
 1 2
 3 4

Right Array:
 4 5
 6 7

Merged Array:
 1 2 4 5

Process finished with exit code -1073741819 (0xC0000005)
c
asked on Stack Overflow Nov 20, 2020 by fouroctets

1 Answer

0

You are mixing two different matrix representations.

The left and right array are two dimensional:

    leftArray = calloc(sizeof(int **), leftRows);
    for (i = 0; i < leftRows; i++)
        *(leftArray+i) = calloc(sizeof(int *), leftCols);

The merged array is one dimensional

    retArray = calloc(sizeof(int), retRows * retCols);

The same print function cannot print both representations.

You should choose one matrix representation and stick to it.


Further to your comment, if you change MergeArray2D to something like this and fix up the types in main you should be good.

int  MergeArray2D( int ***retArrayPtr, int *retRowsPtr, int *retColsPtr,
                   int **leftArray, int leftRows, int leftCols,
                   int **rightArray, int rightRows, int rightCols )
{
    int  **retArray;
    int  i;
    int  j;
    int  retCols;
    int  retRows;

    if ((retArrayPtr == NULL) || (retColsPtr == NULL) || (retRowsPtr == NULL) || (leftArray == NULL))
        return (-1);

    retCols = leftCols + rightCols;
    retRows = MAX(leftRows, rightRows);
    
    retArray = calloc(sizeof(int **), retRows);
    for (i = 0; i < retRows; i++)
        *(retArray+i) = calloc(sizeof(int *), retCols);
    /* TODO: Add error checking here */

    /* First copy the left array into the merged array */
    for (i = 0; i < leftRows; i++) {
        for (j = 0; j < leftCols; j++) {
            retArray[i][j] = leftArray[i][j];
        }
    }

    /* And then copy the right array into the merged array */
    for (i = 0; i < rightRows; i++) {
        for (j = 0; j < rightCols; j++) {
            retArray[i][j+leftCols] = rightArray[i][j];
        }
    }

    *retArrayPtr = retArray;
    *retColsPtr = retCols;
    *retRowsPtr = retRows;

    return (0);
}

I would note, you would have now repeated that matrix allocation code three times in your program. You should probably consider factoring that out into a function. You'll probably also need a matrix deallocation function too. While you are doing this, you might think about whether you should create a matrix struct to keep all the information about a matrix together.

answered on Stack Overflow Nov 20, 2020 by idz • edited Nov 20, 2020 by idz

User contributions licensed under CC BY-SA 3.0