# 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

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.

User contributions licensed under CC BY-SA 3.0