I wrote this code that inputs 2 matrices and prints the product after multiplying the 2 matrices using pointers. But when I enter the first element I am getting segmentation fault. I have tried everything with pointers but I think this is some loop error as it says segmentation fault. Please help
#include<stdio.h>
#include<stdlib.h>
#define N 10
void readMatrix(float *arrp, int rows, int cols)
{
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols; j++)
{
printf("Enter element [%d][%d] : ",i+1,j+1);
scanf("%f",&*(arrp + i) + j);
}
}
return;
}
void printMatrix(float *arrp, int rows, int cols)
{
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols; j++) printf("%.2f\t",*((arrp + i) + j));
printf("\n");
}
return;
}
int main()
{
float *ap, *bp, *cp;
int arows, brows, acols, bcols;
printf("Give no. of rows of matrix A (<=%d) = ",N);
scanf("%d",&arows);
printf("Give no. of columns of matrix A (<=%d) = ",N);
scanf("%d",&acols);
if (arows>N || acols>N || arows<1 || acols<1)
{
printf("Illegal rows/cols = %d/%d. Should be <=%d.\n", arows, acols, N);
exit(0);
}
readMatrix(ap, arows, acols); printf("\n");
printf("Matrix A :\n"); printMatrix(ap, arows, acols); printf("\n");
printf("Give no. of rows of matrix B (<=%d) = ", N);
scanf("%d",&brows);
printf("Give no. of columns of matrix B (<=%d) = ", N);
scanf("%d",&bcols);
if (brows>N || bcols>N || brows<1 || bcols<1)
{
printf("Illegal rows/cols = %d/%d. Should be <=%d.\n", brows, bcols, N);
exit(0);
}
if (acols==brows)
{
readMatrix(bp, brows, bcols); printf("\n");
printf("Matrix B :\n"); printMatrix(bp, brows, bcols); printf("\n");
for (int i=0; i<arows; i++)
{
for (int j=0; j<bcols; j++)
{
float sum=0.0;
for (int k=0; k<acols; k++) sum += *((ap + i) + k) * *((bp + k) + j);
*((cp + i) + j) = sum;
}
}
printf("After Multiplication, Matrix C :\n"); printMatrix(cp, arows, bcols);
}
else printf("\nIncompatible matrices\nColumns of matrix A should be equal to rows of matrix B\n");
exit(0);
}
Your program never assigns any values to ap, bp, or cp. You need to reserve memory for the data in some way and set the pointers to point to it.
Additionally, *((ap + i) + k) is equivalent to *(ap + (i + k)). It merely adds i and k. The program needs to compute where the element in row i and column k is. If ap is a pointer to float, you need to multiply i by the number of columns. If ap is a pointer to an array, you need to insert another operator in there—go back to your source material for the class and see what is different about this expression than what the book or the instructor taught.
Related
I'm new to coding and new to C++. I am trying to write code in which one enters elements of the matrix. Afterwards, one column should be removed, and one row should be added. Removing one column works fine. However, after reallocating memory for the new number of rows, I get the message: segmentation fault (core dumped). I am using pointers to create and edit my matrix. Here is my code. Thanks for any help!
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,r,**p,column,row;
printf("Enter the number of rows and columns:\n");
scanf("%d\n%d",&r,&c);
p=(int**)calloc(r,sizeof(int*));
if(p==NULL) printf("Memory not allocated.\n");
else{
for(int i=0;i<r;i++){
*(p+i)=(int*)calloc(c,sizeof(int));
printf("Enter %d. row\n",i+1);
for(int j=0;j<c;j++){
scanf("%d",*(p+i)+j);
}
}
printf("Original matrix:\n");
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
printf("%d ",*(*(p+i)+j));
}
printf("\n");
}
printf("Which column do you want to remove?");
scanf("%d",&column);
while(column<1||column>c){
printf("Wrong entry, enter again:");
scanf("%d",&column);
}
for(int i=0;i<=r-1;i++){
for(int j=column-1;j<=c-2;j++)
*(*(p+i)+j)=*(*(p+i)+j+1);
*(p+i)=(int*)realloc(*(p+i),(c-1)*sizeof(int));
}
printf("Matrix without %d. column:\n",column);
for(int i=0;i<r;i++){
for(int j=0;j<c-1;j++)
printf("%d ",*(*(p+i)+j));
printf("\n");
}
printf("Which row do you want to replace?\n");
scanf("%d",&row);
while(row<1||row>r){
printf("Wrong entry, enter again:\n");
scanf("%d",&row);
}
p=(int**)realloc(p,(r+1)*sizeof(int*));
if(p==NULL)
printf("Memory not allocated.\n");
else{
printf("Enter %d. row",row);
for(int i=r+1;i>row-1;i++){
*(p+i)=*(p+i-1);
}
for(int j=0;j<c-2;j++)
scanf("%d",*(p+row-1)+j);
printf("New matrix:\n");
for(int i=0;i<=r;i++){
for(int j=0;j<c-2;j++)
printf("%d ",*(*(p+i)+j));
printf("\n");
}
}
}
return 0;
}
When you realloc memory for p, you add one new row to that array (one additional pointer). But you never allocate the memory for that new row, and eventually you access this uninitialized pointer.
But that's not the real problem. In the loop where you want to bump the pointers up to make space for the inserted row, your initial value and loop increment are both wrong. With an initial value of int i=r+1, the first write to *(p+i) will access one past the allocated space (which would be p[0] thru p[r]). The loop increment should be a decrement, --i. Once this loop is done, then you can allocate space for the new row.
As other people here have stated, it is definitely easier to do this using std::vector.
However, I assume you are doing this as a learning exercise so I would definitely recommend you to finish this and understand where you went wrong. You were close, it looks like you just got confused with your indices. Try using more descriptive variable names and splitting stuff into functions to make it harder to get lost in your own code.
I modified your code to get it to do what i think you were trying to do. Take a look and let me know if that was helpful.
But yes, if you do any future C++ work, avoid doing C style malloc, alloc, free, etc... and consider working with the std libs.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c, r, ** p, column, row;
printf("Enter the number of rows and columns:\n");
scanf_s("%d\n%d", &r, &c);
p = (int**)calloc(r, sizeof(int*));
if (p == NULL) printf("Memory not allocated.\n");
else {
for (int i = 0; i < r; i++) {
*(p + i) = (int*)calloc(c, sizeof(int));
printf("Enter %d. row\n", i + 1);
for (int j = 0; j < c; j++) {
scanf_s("%d", *(p + i) + j);
}
}
printf("Original matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d ", *(*(p + i) + j));
}
printf("\n");
}
printf("Which column do you want to remove?");
scanf_s("%d", &column);
while (column<1 || column>c) {
printf("Wrong entry, enter again:");
scanf_s("%d", &column);
}
for (int i = 0; i <= r - 1; i++) {
for (int j = column - 1; j <= c - 2; j++)
* (*(p + i) + j) = *(*(p + i) + j + 1);
*(p + i) = (int*)realloc(*(p + i), (c - 1) * sizeof(int));
}
c -= 1;
printf("Matrix without %d. column:\n", column);
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
printf("%d ", *(*(p + i) + j));
printf("\n");
}
printf("Which row do you want to replace?\n");
scanf_s("%d", &row);
while (row<1 || row>r) {
printf("Wrong entry, enter again:\n");
scanf_s("%d", &row);
}
p = (int**)realloc(p, (r + 1) * sizeof(int*));
if (p == NULL)
printf("Memory not allocated.\n");
else {
printf("Enter %d. row", row);
for (int i = 0; i < c; i++)
scanf_s("%d", *(p + row -1) + i);
printf("New matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
printf("%d ", *(*(p + i) + j));
printf("\n");
}
}
}
return 0;
}
User is asked to give a number of rows and columns to fill an array of 10x10 array with random numbers.(A part of the table will be filled e.g 2x2). Then a function called printArray will print its values.Then,function change_array will find in every row the biggest value and replace the elements left of it with the value.
For instance:
Initial Array
<p>41 67 34 0 </p>
<p>69 24 78 58</p>
<p>62 64 5 45</p>
changed Array
<p>67 67 34 0 </p>
<p>78 78 78 58 </p>
<p>64 64 5 45 </p>
However,the program gives this:
Initial Array
<p>41 67</p> <p>34 0</p>
Changed Array
<p>67 67</p>
<p>24576000 508</p>
Why is this happening?
simpio.h gets an input of integer value
This can't be done with pointers(We are not there yet in class)
The modified array must be printed in main()
#include <stdio.h>
#include <stdlib.h>
#include "simpio.h"
void populate_data(int R, int C, int A[R] [C]);
void printArray(int R, int C, int A[R] [C]);
void change_array(int R, int C, int A[R] [C]);
int main(void)
{
int A[10] [10],R,C,i,j;
while (TRUE)
{
printf("Give the number of rows: ");
R = GetInteger();
if (R>=0 && R<=10)
break;
else
{
printf("Wrong Answer\n");
}
}
while (TRUE)
{
printf("Enter the number of columns: ");
C = GetInteger();
if (C>=0 && C<=10)
break;
else
{
printf("Wrong Answer\n");
}
}
populate_data(R,C,A);
printf("Initial Array\n");
printArray(R,C,A);
change_array(R,C,A);
printf("Changed Array\n");
for (i=0; i<R; i++)
{
for (j=0; j<C; j++)
{
printf("%d ",A[i] [j]);
}
printf("\n");
}
return 0;
}
void populate_data(int R, int C, int A[R] [C])
{
int i,j;
for (i=0; i<R; i++)
{
for (j=0; j<C; j++)
{
A[i] [j] = rand() % 100;
}
}
}
void printArray(int R, int C, int A[R] [C])
{
int i,j;
for (i=0; i<R; i++)
{
for (j=0; j<C; j++)
{
printf("%-3d ",A[i] [j]);
}
printf("\n");
}
}
void change_array(int R, int C, int A[R] [C])
{
int i, j, max[R], m[R];
for (i=0; i<R; i++)
{
max[i] = A[i] [0];
for (j=0; j<C; j++)
{
if (max[i]< A[i] [j])
{
max[i] =A[i] [j];
m[i] = j;
}
}
}
for (i=0; i<R; i++)
{
for (j=0; j<C; j++)
{
if (j<m[i])
A[i] [j] = max [i];
}
}
}
This happens if the max value in a row is on first position, so you will never enter this block
if (max[i]< A[i] [j])
{
max[i] =A[i] [j];
m[i] = j;
}
and m[i] will stay uninitialized. Just add a
m[i] = 0;
before that loop.
Edit:
You must change your function definitions from A[R][C] to A[10][10], because R and C are unknown to the function at that point.
Also, there is no reason to declare the array with size 10x10. You can do that after you got the dimension from input with the correct number of rows and columns.
This is a problem for my homework assignment but I am stuck trying to print out the array. The program will prompt the user for the "number of rows" and the "number of columns" but will terminate immediately without printing anything and I am not sure why this is happening.
Also my sorting function doesn't work. The code gives me errors about pointers but am not too familiar with them at this point. If there is a way to do without pointers, I guess that would be better. But if the best method is to use pointers, please include that. The help would be much appreictaed
warning: assignment makes integer from pointer without a cast [-Wint-conversion]
temp = A[i];
error: assignment to expression with array type
A[i] = A[j];
error: assignment to expression with array type
A[j] = temp;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N1 100
#define M1 100
void fillMatrix(int A[][M1], int N, int M);
int sortMatrix(int A[][M1],int rowsize, int colsize);
void displayArray(int A[][M1], int N, int M);
int main(void)
{
int array[N1][M1] = {0};
fillMatrix(array, N1, M1);
displayArray(array, N1, M1);
//sortMatrix(array, N1, M1);
return 0;
}
void fillMatrix(int A[][M1], int N, int M)
{
int rows = 0, columns = 0;
//ASK FOR ROWS
printf("Enter a number of rows: ");
scanf("%i", &rows);
if(rows < 0 && rows >= 100)
{
printf("Invalid Input.\n");
printf("Enter a number of rows: ");
scanf("%i", &rows);
}
//ASK FOR COLUMNS
printf("Enter a number of columns: ");
scanf("%i", &columns);
if(columns < 0 && columns >= 100)
{
printf("Invalid Input.\n");
printf("Enter a number of columns: ");
scanf("%i", &columns);
}
//FILLS ARRAY W/ RANDOM INT VALUES BETWEEN 0 AND 100
srand(time(NULL));
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < columns; j++)
{
A[i][j] = 0 + rand() % 100;
}
}
}
/*int sortMatrix(int A[][M1],int rowsize, int colsize)
{
int temp = 0;
for(int i = 0; i < rowsize; i++)
{
for (int j = 0 ; j < colsize; j++)
{
if(A[i] > A[j])
{
temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
}
return 0;
}*/
void displayArray(int A[][M1], int N, int M)
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
printf("%i ", A[i][j]);
}
}
}
Yeah, well. First of all sortMatrix(int A[][M1].... In that case, you are passing a pointer to the array row. In C++ there is no other way to pass the array to function, only via pointers.
Look over there.
Secondly, when you do something like this A[i] > A[j], you are comparing pointers of rows (In general, comparing pointers is UB, by the way. But, in your case, that is just comparing rows addresses, which is still, not what you should do when you want to sort array).
I propose this A[i][M1] > A[j][M1]. That way, you will compare elements.
Last, but not least.
but will terminate immediately without printing anything
Are you mean that console window is closing immediately? In that case, you may need to add cin.get(); to your code, after printing array, or system("pause");, in case you are using clear C, or something like this, if not.
UPD.
If you are using clean C, then instead cin.get(); you should use getchar();.
And system("pause"); truly only Windows thing.
p.s. Also, read other notes from Paul Ogilvie and Mike Housky. They are writing good things.
p.p.s. Pardon, if there is any mistake. English, not my first language, so feel free to edit the answer.
If you have any questions, please do not hesitate to contact me. I will try to answer.
The function fillMatrix retrieves two important values from the user, rows and columns, which are needed throughout the program, but these values are lost when the function exits. You then proceed to use fixed values N1 and M1
You should change the function to void fillMatrix(int A[][M1], int *set_rows, int *set_columns) and pass rows and columns by reference so that their values are saved.
if(rows < 0 && rows >= 100)
{
printf("Invalid Input.\n");
printf("Enter a number of rows: ");
scanf("%i", &rows);
}
The valid range for rows should be from 1 to M1. You should also be prepared in case the user enters the wrong value a second time.
There is no standard method to sort the values in a matrix. Do you want to sort each row? You can use qsort to sort a 1-D array.
#define TOTAL_ROWS 100
#define TOTAL_COLUMNS 100
void fillMatrix(int A[][TOTAL_COLUMNS], int *set_rows, int *set_columns)
{
int rows = 0, columns = 0;
//ASK FOR ROWS
while(1)
{
printf("Enter a number of rows: ");
scanf("%i", &rows);
if(rows > 0 && rows < TOTAL_ROWS)
break;
printf("Invalid Input.\n");
}
//ASK FOR COLUMNS
while(1)
{
printf("Enter a number of columns: ");
scanf("%i", &columns);
if(columns > 0 && columns < TOTAL_COLUMNS)
break;
printf("Invalid Input.\n");
}
for(int i = 0; i < rows; i++)
for(int j = 0; j < columns; j++)
A[i][j] = rand() % 100;
*set_rows = rows;
*set_columns = columns;
}
int compare(const void *a, const void *b)
{
return (*(int*)a - *(int*)b);
}
void sortMatrix(int A[][TOTAL_COLUMNS], int rowsize, int colsize)
{
for(int r = 0; r < rowsize; r++)
qsort(A[r], colsize, sizeof(int), compare);
}
void displayArray(int A[][TOTAL_COLUMNS], int rows, int columns)
{
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < columns; j++)
printf("%3i ", A[i][j]);
printf("\n");
}
}
int main(void)
{
srand((unsigned int)time(NULL));
int array[TOTAL_ROWS][TOTAL_COLUMNS] = { 0 };
int rows, columns;
fillMatrix(array, &rows, &columns);
sortMatrix(array, rows, columns);
displayArray(array, rows, columns);
return 0;
}
If you are to use your own sort, or bubble sort specifically, write a simple bubble sort function for a 1-D array, then sort the matrix 1 row at a time:
void bubble_sort(int *arr, int count)
{
for(int i = 0; i < count - 1; i++)
{
for(int j = 0; j < count - i - 1; j++)
{
if(arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void sortMatrix(int A[][TOTAL_COLUMNS], int rowsize, int colsize)
{
for(int r = 0; r < rowsize; r++)
bubble_sort(A[r], colsize, sizeof(int), compare);
}
Lastly, if rows and columns are not known ahead of time, declaring int array[100][100] is not best way. In gcc compiler you can use variable array. In Visual Studio you have to use malloc in order to dynamically allocate the array based on what the user chooses for rows and columns.
I can't seem to find any info on how to access elements of an array via pointer in a function, I tried following multiple answers but none of them seem to work for me.
My task is next: Write a program in C with m x n dimension with elements being randomly generated from 0 to 9. Using two new functions calculate the sum of even elements and count the number of elements being equal to zero.
#include <stdio.h>
#include <stdlib.h>
void SumEven(int *a, int n, int m, int *sum){
}
void EqualToZero(int *a, int n, int m, int *number){
}
int main()
{
int** a;
int m, n, l, i, j, r, sum;
printf("Enter number of columns for matrix: ");
scanf("%d", &m);
printf("Enter number of rows for matrix: ");
scanf("%d", &n);
a = (int **) malloc(m*sizeof(int));
for (l = 0 ; l < m ; l++){
a[l] = (int **) malloc(n*sizeof(int));
}
time_t t;
srand((unsigned)time(&t));
printf("\n");
printf("Your matrix is:\n");
printf("\n");
for(i = 0 ; i < m ; i++){
for(j = 0 ; j < n ; j++){
r = rand() % 10;
a[i][j] = r;
printf("%d ", r);
}
printf("\n");
}
printf("\n");
SumEven(&a, n, m);
return(0);
}
As you can see in the provided code I left those functions empty as I don't know how to pass the matrix to them and access their elements so I can be able to print my results.
Also my pseudo code for the logic for the functions themselves are:
if(a[i][j] % 2 == 0)
printf("%d ", a[i][j])
and
if(a[i][j] == 0)
printf("%d ", a[i][j])
Also those parameters of the function are predefined in my task, so I have to follow them.
EDIT: I also don't know if I'm even passing the same matrix to the function with SumEven(&a, n, m);. I tried outputing the address of the matrix and using printf("%d", &a) to display an address both from main() and SumEven() functions.
This code may help. It does the following:
1. For an arbitrary array of integers, sum the elements of the array
- using a pointer to the SUM function
2. For an arbitrary array of integers, count the number of zero elements in
the array - using a pointer to the COUNTZERO function
#include <stdio.h>
#include <stdlib.h>
// sum the elements of the matrix
void sum(int* arr, int rows, int cols, int* result)
{
int sum = 0;
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
sum = sum + arr[i*cols + j];
}
}
*result = sum;
}
// count the number of zero elements in the matrix
void countZero(int* arr, int rows, int cols, int* result)
{
int count = 0;
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (arr[i*cols + j] ==0) count = count + 1;
}
}
*result = count;
}
// arbitrary initialisation of 2D array of ints (force last entry of the array to equal zero - for testing purposes)
void init2D(int *arr, int rows, int cols) {
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
arr[i*cols + j] = 1;
}
}
// use this to test the countZero function
arr[(rows-1)*(cols-1)] = 0;
}
int main() {
int *array; // will hold a 2D array of integers
int N = 10; // arbitrary number of rows
int M = 5; // arbitrary num cols
// 2D array of integers expressed as one "contiguous row" of memory
// make sure your indexing is correct when referenceing the array for (i,j)th element
array = (int*)malloc(sizeof(int)*N*M);
if (array != NULL) {
init2D(array, N, M);
}
// the function pointer
void(*general)(int*,int,int,int*);
// will contain the sum result
int sumAll = 0;
int* ptsumAll = &sumAll;
// make the function pointer point to the sum function
general = ∑
// sum the contents of the array
general(array,N,M, ptsumAll);
printf("sum of array elements: %d\n", *ptsumAll);
// contains a count of the zero elements in the array
int count =0;
int* ptcount = &count;
// make the function pointer point to the count function
general = &countZero;
// count the number of zero element in the array
general(array, N, M,ptcount);
printf("number of zeros: %d\n", *ptcount);
free(array);
return 0;
}
some references:
https://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html
http://www.cprogramming.com/tutorial/function-pointers.html
I have added comments to help you with the code.
#include <stdio.h>
#include <stdlib.h>
void SumEven(int *a, int n, int m, int *sum){
//put this statement in 2 nested for loops of size n and m
if(a[i][j] % 2 == 0)
sum += a[i][j];
}
void EqualToZero(int *a, int n, int m, int *number){
//put this statement in 2 nested for loops of size n and m
if(a[i][j] == 0)
number++;
}
int main()
{
int** a;
int m, n, l, i, j, r, sum;
printf("Enter number of columns for matrix: ");
scanf("%d", &m);
printf("Enter number of rows for matrix: ");
scanf("%d", &n);
a = (int **) malloc(m*sizeof(int));
//should be m*sizeof(int*)
for (l = 0 ; l < m ; l++){
a[l] = (int **) malloc(n*sizeof(int));
//should be cast as (int*)
}
//I suggest you take look at declaring 2d arrays in C
time_t t;
srand((unsigned)time(&t));
printf("\n");
printf("Your matrix is:\n");
printf("\n");
for(i = 0 ; i < m ; i++){
for(j = 0 ; j < n ; j++){
r = rand() % 10;
a[i][j] = r;
printf("%d ", r);
}
printf("\n");
}
printf("\n");
SumEven(&a, n, m);
//need to pass &sum to this function. Also make sure it is initialized to 0
//call EqualToZero() function with proper parameters.
return(0);
//return 0; not return(0);
}
These will be your function prototypes:
void SumEven(int **a, int n, int m,int *sum);
void EqualToZero(int **a, int n, int m,int *number);
since you are passing a(double pointer) from calling then the there should be a double pointer(int **a) to receive it.
Calling:
SumEven(a, n, m,&sum);
EqualToZero(a, n, m,&number);
And this is how you can access the array inside your function:
void SumEven(int **a, int n, int m,int *sum){
int i,j,tsum=0;
for(i = 0 ; i < m ; i++){
for(j = 0 ; j < n ; j++){
if(a[i][j] % 2 == 0)
{
tsum+=a[i][j];
printf("%d ",a[i][j]);
}
}
}
*sum=tsum;
}
Also there is an error in this line a[l] = (int **) malloc(n*sizeof(int)); (‘int**’ to ‘int*’assignment),it should be a[l] = (int *) malloc(n*sizeof(int));.
Here's an example, given a 3D array
int buffer[5][7][6];
An element at location [2][1][2] can be accessed as buffer[2][1][2] or *( *( *(buffer + 2) + 1) + 2).
Reference
if(( *(*(a + i) + j) % 2 ) == 0 )
printf("%d", *(*(a + i) + j) )
if( *(*(a + i) + j) == 0 )
printf("%d", *(*(a + i) + j) )
This is how you do it.
There is segmentation fault in case 5 of this program(transpose) this segmentation fault occurs only when the input row is greater than that of the input column. Hopefully this is due to the reason I have not allocated the memory accordingly.
b= (int**)malloc(r*sizeof(int*));
for(i=0; i<c; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
And if I am doing it accordingly like this:
b= (int**)malloc(c*sizeof(int*));
for(i=0; i<r; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
there still is seg. fault and this time it is not producing correct output for matrix of any order.
Here is my full code :
#include<stdio.h>
#include<stdlib.h>
int** inputmatrix(int **a,int r, int c)
{
int i, j;
a = (int**)malloc(r*sizeof(int));
for(i=0; i<c; i++)
{
a[i] = (int*)malloc(sizeof(int));
}
printf("\n Input the Elements of the Matrix :");
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
scanf("%d",&a[i][j]);
}
}
return a;
}
void showmatrix(int** a, int r, int c)
{
int i, j;
for(i=0; i<r; i++)
{
printf("\n");
for(j=0; j<c; j++)
{
printf(" %d",a[i][j]);
}
}
}
int** add(int **a, int **b, int r, int c)
{
int i,j;
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
a[i][j] = a[i][j]+b[i][j];
}
}
return a;
}
int** multiplication(int** a, int **b, int r1, int c1, int c2)
{
int **c,i,j,k;
c = (int**)malloc(r1*sizeof(int*));
for(i=0; i<c2; i++)
{
c[i] = (int*)malloc(sizeof(int));
}
for(i=0; i<r1; i++)
{
for(j=0; j<c2; j++)
{
c[i][j] = 0;
for(k=0; k<c1; k++)
{
c[i][j] = c[i][j] + a[i][k]*b[k][j];
}
}
}
return c;
}
int minval(int **a, int r, int c)
{
int i, min;
min = a[r][0];
for(i=0; i<c; ++i)
{
if(a[r][i]<min)
{
min = a[r][i];
}
}
return min;
}
int maxval(int **a, int r, int c)
{
int i, max;
max = a[0][c];
for(i=0; i<r; ++i)
{
if(a[i][c] > max )
{
max = a[i][c];
}
}
return max;
}
void saddlepoint(int **a, int r, int c)
{
int i, j, rpos, cpos, flag = 0,sp;
for(i=0; i<r; ++i)
{
for(j=0; j<c; ++j)
{
if(a[i][j] == minval(a, i, c) && a[i][j] == maxval(a, r, j))
{
sp = a[i][j];
flag = 1;
rpos = i;
cpos = j;
}
}
}
if(flag == 1)
{
printf("\n The Saddle point of the Matrix is found at position (%d,%d) value is %d ", rpos, cpos,sp);
}
else
{
printf("\n There is no saddle point in the Matrix ");
}
}
int magicsquare(int **a, int r, int c)
{
int i, j, row_sum, col_sum, d1, d2, flag = 0;
if(r==c)
{
for(i =0 ;i<r; i++) // for digonals
{
d1 = d1 + a[i][i];
d2 = d2 + a[i][r-i-1];
}
for(i=0; i<r; i++)
{
row_sum = 0;
for(j=0; j<c; j++)
{
row_sum = row_sum + a[i][j];
}
if(row_sum == d1)
flag = 1;
else
break;
}
for(i=0; i<r; i++)
{
col_sum = 0;
for(j=0; j<c; j++)
{
col_sum = col_sum + a[j][i];
}
if(col_sum == d1)
flag =1;
else
break;
}
}
else
{
printf("\n This Matrix is not a Magic Square ");
}
return flag;
}
int** transpose(int **a, int r, int c)
{
int i, j, **b;
b= (int**)malloc(c*sizeof(int*));
for(i=0; i<r; i++)
{
b[i] = (int*)malloc(sizeof(int));
}
for(i =0; i<r; i++)
{
for(j=0; j<c; j++)
{
b[j][i] = a[i][j];
}
}
return b;
}
int main()
{
int **a, **b,r1,c1,r2,c2, i,j,ch,f;
int **c;
printf("\n enter your choice : \n1.Addition \n2.Multiplication \n3.Saddle Point \n4. Magic Square \n5.Transpose\n");
scanf("%d",&ch);
printf("\n enter the oder of matrix A :");
scanf("%d%d",&r1,&c1);
a = inputmatrix(a,r1,c1);
switch(ch)
{
case 1:
printf("\n enter the oder of matrix B :");
scanf("%d%d",&r2,&c2);
if(r1==r2 && c1==c2)
{
b = inputmatrix(b,r2,c2);
a = add(a,b,r1,c1);
printf("\n the result of the addition of matrices is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0;j<c1; j++)
{
printf("%d\t",a[i][j]);
}
}
}
else
{
printf("\n these matrices can't be added ");
}
break;
case 2 :
printf("\n Enter the Order of Matrix B :");
scanf("%d%d",&r2,&c2);
b = inputmatrix(b,r2,c2);
if(c1 == r2)
{
c = multiplication(a, b, r1, c1, r2);
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c2; j++)
{
printf("%d\t",c[i][j]);
}
}
}
else
{
printf("\n Sorry, These Matrices Can't be Multiplied ");
}
break;
case 3 :
printf("\n The Matrix you Entered is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c1; j++)
{
printf(" %d",a[i][j]);
}
}
saddlepoint(a,r1,c1);
break;
case 4 :
printf("\n The Matrix you Entered is :");
for(i=0; i<r1; i++)
{
printf("\n");
for(j=0; j<c1; j++)
{
printf(" %d",a[i][j]);
}
}
int f = magicsquare(a, r1, c1);
if(f==1)
printf("\n This Matrix is a Magic Square ");
else
printf("\n This Matrix is not a Magic Square ");
break;
case 5 :
printf("\n The Matrix you enter is :");
showmatrix(a,r1,c1);
b = transpose(a,r1,c1);
printf("\n the transpose of the entered matrix is :");
for(i=0; i<c1; i++)
{
printf("\n");
for(j=0; j<r1; j++)
{
printf(" %d",b[i][j]);
}
}
break;
default : printf("\n Sorry, This is a Wrong Choice ");
}
return 0;
}
A few Output cases are also below:
case 1:
enter your choice :
1.Addition
2.Multiplication
3.Saddle Point
4. Magic Square
5.Transpose
5
enter the oder of matrix A :3
2
Input the Elements of the Matrix :1
2
3
4
5
Segmentation fault (core dumped)
case 2:
enter your choice:
1.Addition
2.Multiplication
3.Saddle Point
4. Magic Square
5.Transpose
5
enter the oder of matrix A :2
3
Input the Elements of the Matrix :1
2
3
4
5
6
The Matrix you enter is :
1 2 3
4 5 6
the transpose of the entered matrix is :
1 4
2 5
3 6
And there is some problem in the multiplication function also, there also right matrix is not being displayed.
b= (int**)malloc(r*sizeof(int*));
This allocates an array of r int* elements.
for(i=0; i<c; i++)
This goes over the first c elements of this array. If c>r, then
b[i] = (int*)malloc(sizeof(int));
the behaviour of the line above is undefined. If c<=r, it is well-defined but not very useful, as it allocates one element for each matrix row. It probably becomes broken later, when you try to access elements past the first column.
To allocate a matrix with r rows and c columns you probably want to do this:
b = malloc(r * sizeof(int*)); /* allocate `r` rows */
for(i = 0; i < r; i++) /* for each of the `r` rows */
b[i] = malloc (c * sizeof(int)); /* allocate `c` columns */
There is mistake in the declaration of the arrays using malloc.
When you wish to declare a 2-D array of 'r' rows and 'c' columns, the statements should be something like
int **arr=malloc(r*sizeof(int *));
for(i=0;i<r;i++)
arr[i]=malloc(c*sizeof(int));
This will eliminate the segmentation fault.
The first statement declares an array of 'r' integer pointers.
The for loop executes 'r' times since you have to initialize each of the 'r' pointers declared by the previous statement.
The statement inside the for loop declares an integer array of length 'c' to store 'c' elements of each row.
Moreover, it initializes each of the pointers of the array 'arr' with the addresses of these rows(in correct order of-course).
Thus we get 'r' rows of 'c' elements each and hence an (r x c) matrix.