Reputation: 1533
I was given an assignment to create a program that gets a 2d array, number of rows and number of columns, and then return the transposed matrix and print it, using only pointer arithmetic, no [] allowed.
My code is working perfectly. It does indeed print the transposed matrix, but after that, i get the following message:
Windows has triggered a breakpoint in First Assignment.exe.
This may be due to a corruption of the heap, which indicates a bug in First Assignment.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while First Assignment.exe has focus.
The output window may have more diagnostic information.
Can anyone help me with this? I have no idea what's wrong. This is my code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int** allocate_matrix(int rows,int columns);
void print_matrix(int** mat1,int rows, int columns);
void scan_matrix(int** mat1,int rows, int columns);
int** transpose_matrix(int** mat1, int rows, int columns);
void main()
{
int** mat1;
int** trans_mat1;
int rows,columns;
printf("Enter the number of rows and columns you wish to see\n");
printf("Rows:");
scanf("%d",&rows);
printf("Columns:");
scanf("%d",&columns);
mat1 = allocate_matrix(rows,columns);
scan_matrix(mat1,rows,columns);
printf("the matrix you entered is: \n");
print_matrix(mat1,rows,columns);
printf("The transposed matrix is:\n");
trans_mat1 = transpose_matrix(mat1,rows,columns);
print_matrix(trans_mat1,columns,rows);
getch();
free(mat1);
free(trans_mat1);
}
int** allocate_matrix(int rows,int columns)
{
int i;
int** ptrmatrix;
ptrmatrix = (int**)malloc(rows*sizeof(int*));
for(i=0;i<rows;i++)
*(ptrmatrix+i) = (int*)malloc(columns*sizeof(int));
return ptrmatrix;
}
void print_matrix(int** mat1,int rows, int columns)
{
int i,j;
for(i=0;i<rows;i++)
{
for(j=0;j<columns;j++)
printf("%d ",*(mat1+i*columns+j));
printf("\n");
}
}
void scan_matrix(int** mat1,int rows, int columns)
{
int i,j;
for(i=0;i<rows;i++)
{
printf("Enter %d values for row number %d\n",columns,i+1);
for(j=0;j<columns;j++)
scanf("%d",(mat1+i*columns+j));
}
}
int** transpose_matrix(int** mat1,int rows,int columns)
{
int i,j;
int** trans_mat1;
trans_mat1 = allocate_matrix(columns,rows);
for(i=0;i<rows;i++)
for(j=0;j<columns;j++)
*(trans_mat1+(j*rows)+i)=*(mat1+(i*columns)+j);
return trans_mat1;
}
Upvotes: 0
Views: 6278
Reputation: 4528
There seems to be an error in your pointer arithmetic that is causing the problem.
printf("%d ",*(mat1+i*columns+j));
Should be:
printf("%d ",*(*(mat1+i)+j));
It seems that you misunderstood how you are allocating your matrix. Normally in these kinds of assignments you would allocate your matrix as a single array of NxM integers and then use the formula that you initially used.
Example:
int rows = 7, cols = 9;
int* matrix = (int*) malloc(rows * cols * sizeof(int));
// Get 3rd row and 5th column value
int value = *(matrix + 3 * rows + 5);
But what you are doing is allocating an array of pointers to arrays of integers. Each integer array is a row in your code. So what you need to do is first access the correct pointer in the array of pointers (mat + i)
(which signifies a pointer to the ith row array) , get the pointer value *(mat+i)
and then access the correct column value. Here's a play by play for your example:
int rows = 9, cols = 21;
// Allocate the array of pointers to rows
int** matrix = (int**) malloc(rows * sizeof(int*));
// Allocate each row as an array of values
for (int j = 0; j < rows; ++j)
{
*(matrix + j) = (int*) malloc(cols * sizeof(int));
}
// Access the value at row 5, column 7
int* rowPtr = *(matrix + 5);
int value = *(rowPtr + 7);
Edit: Other suggestions
Dealocation: @mikyra's answer has also advised to deallocate your array's after use. I also recommend this but won't include it in my answer since he has already done the work in his. Please give him credit for it.
Memory efficiency: Allocating the extra array of pointers uses more memory than using a single array of NxM size, provided that all rows are allocated. If you have some logic that tries to leave empty rows unallocated you could get better memory performance but it would only be beneficial for large, sparse matrices which I believe is beyond the scope of your assignment.
I personally prefer the single array approach as it is simpler to allocate/deallocate and index.
Upvotes: 3
Reputation: 10367
You really didn't do yourself a favor in deciding on not just allocating a row x column memory block for your matrix operations. Especially if this is intended as a beginners exercise in pointer-arithmetic.
The right expression to access the value of the cell in row i and column j is in fact this one:
*((*(mat1 + i))+j)
Using the following corrected versions everything should work as expected:
void print_matrix(int** mat1,int rows, int columns)
{
int i,j;
for(i=0;i<rows;i++)
{
for(j=0;j<columns;j++)
/* this line has been changed */
printf("%d ", *((*(mat1 + i))+j));
printf("\n");
}
}
void scan_matrix(int** mat1,int rows, int columns)
{
int i,j;
for(i=0;i<rows;i++)
{
printf("Enter %d values for row number %d\n",columns,i+1);
for(j=0;j<columns;j++)
/* this line has been changed */
scanf("%d",(*(mat1+i))+j);
}
}
int** transpose_matrix(int** mat1,int rows,int columns)
{
int i,j;
int** trans_mat1;
trans_mat1 = allocate_matrix(columns,rows);
for(i=0;i<rows;i++)
for(j=0;j<columns;j++)
/* this line has been changed */
*((*(trans_mat1 + j))+i) = *((*(mat1 + i))+j);
return trans_mat1;
}
Nevertheless you still lack a method to free all the memory consumed by your matrices. You'd need something like this:
void deallocate_matrix (void* mat, int rows) {
while (rows--)
free (*(mat + rows));
free (mat);
}
To really free all the allocated memory.
Upvotes: 2