Can someone please explain why my program crashes? - c

I don t get any errors at compilation. The program just crashes when I run it. I tried to print the matrix directly from the generate function and it printed the first line and a bit of the second.
This is my code
void generate(int **a)//*Function to generate a matrix a[i][j]=i+j*
{
int i,j;
for(i=0;i<5;i++){
for(j=0;j<4;j++){
a[i][j]=i+j;
}
}
}
void print(int **a)//*print the resulting matrix from generate function*
{
int i,j;
for(i=0;i<5;i++){
for(j=0;j<4;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
}
int main()
{
int *a=(int*)malloc(5*4*sizeof(int));//*allocating memory for a matrix of 4 lines and 5 columns.*
generate(&a);
print(&a);
}

1) you are allocating a single dimension memory.
a[i][j]=i+j; //is not valid.
Below is the modified code
#include <stdio.h>
#include <stdlib.h>
void generate(int *a)//*Function to generate a matrix a[i][j]=i+j*
{
int i,j;
for(i=0;i<5;i++){
for(j=0;j<4;j++){
*a=i+j;
a++; //increments to next memory location
}
}
}
void print(int *a)//*print the resulting matrix from generate function*
{
int i,j;
for(i=0;i<5;i++){
for(j=0;j<4;j++){
printf("%d ",*(a++)); //notice another way of accessing
}
printf("\n");
}
}
int main()
{
int *a=(int*)malloc(5*4*sizeof(int));//*allocating memory for a matrix of 4 lines and 5 columns.*
generate(a);
print(a); //passing the pointer
free(a); //Always always practice to free the allocated memory, don't ever do this mistake again
return 0;
}

Two things:
First, int ** denotes a pointer to a pointer that points to an int, not a pointer that points to an array of ints.
Second, when you just pass a pointer to some data structure, e.g. an 4x5 array of integers, then the compiler cannot derive the layout of this data structure. I.e. a statement like a[i][j] would require that the compiler "knows" that each row i consists of 4 columns j, such that it can calculate the "place" to which the value should be stored, i.e. a + (4*i) + j. The compiler simply does not know the nr of columns per row, i.e. 4.
To overcome this while keeping the size of the array at least potentially variable (note that "4" and "5" are still hard coded in the function), you could do the following:
void generate(int *a)//*Function to generate a matrix a[i][j]=i+j*
{
int i,j;
for(i=0;i<5;i++){
for(j=0;j<4;j++){
*(a+(i*4+j)) = i+j;
}
}
}
void print(int *a)//*print the resulting matrix from generate function*
{
int i,j;
for(i=0;i<5;i++){
for(j=0;j<4;j++){
printf("%d ", *(a+(i*4+j)));
}
printf("\n");
}
}
int main()
{
int *a=(int*)malloc(5*4*sizeof(int));//*allocating memory for a matrix of 4 lines and 5 columns.*
generate(a);
print(a);
}

Related

scanf function for pointer is not working (for a matrix using pointer to pointer)

this is the program I have written for multiplying two matrices.
#include <stdio.h>
#include <stdlib.h>
void allocate(int **mat,int m,int n)
{
int i;
mat = (int**)malloc(m*sizeof(int*));
for(i=0;i<m;i++)
*(mat+i) = (int*)malloc(n*sizeof(int));
}
void read(int **mat,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
printf("Enter the element in row number %d and column number %d\n",i+1,j+1);
scanf("%d",*(mat+i)+j);
}
}
void multiply(int **mat1,int m,int n,int **mat2,int p,int **prod)
{
int i,j,k;
for(i=0;i<m;i++)
for(j=0;j<p;j++)
{
*(*(prod+i)+j) = 0;
for(k=0;k<n;k++)
*(*(prod+i)+j) += (*(*(mat1+i)+k))*(*(*(mat2+k)+j));
}
}
void PRINT(int **mat,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
printf("%d\t",*(*(mat+i)+j));
}
printf("\n\n\n");
}
}
int main()
{
int m,n,p,**mat1,**mat2,**prod;
printf("Enter the number of rows of the first matrix to be multiplied\n");
scanf("%d",&m);
printf("Enter the number of columns of the first matrix to be multiplied\n");
scanf("%d",&n);
printf("Enter the number of columns of the second matrix to be multiplied\n");
scanf("%d",&p);
allocate(mat1,m,n);
allocate(mat2,n,p);
allocate(prod,m,p);
printf("Enter the entries of the first matrix\n");
read(mat1,m,n);
printf("Enter the entries of the second matrix\n");
read(mat2,n,p);
printf("The first input matrix is\n");
PRINT(mat1,m,n);
printf("The second input matrix is\n");
PRINT(mat2,n,p);
multiply(mat1,m,n,mat2,p,prod);
printf("The product matrix is\n");
PRINT(prod,m,p);
return 0;
}
The scanf function used in the read function definition is not working, it just doesn't allow us to give any input and stops unexpectedly. I have used it the same way in another program to find the trace of a matrix and it is fine there.
Please help me finding the error.
Your allocate function receives a copy of the int ** passed as its first argument and, thus, the variables used as this argument in your main function are not modified by it.
To get round this, you could pass the argument as a "pointer to int**" (i.e. int*** mat) - but this starts to get messy (and you'll need to adjust the code inside allocate accordingly). A better way is to redefine the allocate function to return the created pointer, as such:
int** allocate(int m, int n)
{
int i;
int** mat = malloc(m * sizeof(int*));
for (i = 0; i < m; i++)
*(mat + i) = malloc(n * sizeof(int));
return mat;
}
Then, in your main function, modify the calls to allocate as follows:
mat1 = allocate(m, n);
mat2 = allocate(n, p);
prod = allocate(m, p);
You will (of course) need the proper code (at some point) to free the allocated matrices.
Also, see Do I cast the result of malloc?
Your allocation function is very wrong.
Currently, you allocate the local variable mat in allocate and you don't return it nor pas it by pointer, thus, the value is lost at the end of the function (in c, arguments are always passed by value) and you write on invalid data. You have an undefind behavior and as you are lucky, your program segfaults.
Therefore, when you allocate a data, you have to allocate a pointer to this data. Here your data is a int** . That means that your allocate function must take an int*** as an input.
Your program should work with :
void allocate(int ***mat, int m,int n)
{
int i;
*mat = (int**)malloc(m*sizeof(int*));
for(i=0;i<m;i++)
*(*mat+i) = (int*)malloc(n*sizeof(int));
}
Another (maybe cleaner) way to deal with that issue is to return the allocated mat, like below
int** allocate(int m,int n)
{
int i;
int **mat = (int**)malloc(m*sizeof(int*));
for(i=0;i<m;i++)
*(mat+i) = (int*)malloc(n*sizeof(int));
return mat;
}
Also, to debug this kind of issue, valgrind could be really helpful the next time.

Why am I getting 'segmentation error' while using double pointer as an argument for a 2-D array?

The problem is about taking input of a 4X5 matrix and shifting each of its rows circularly left by 2 places. Like if input is {1,2,3,4,5} the output should be {3,4,5,1,2}. I wrote the following code for the same. But I am getting 'segmentation fault(core dumped)' error. Can you help me with this. Also I am a bit susceptible about sending a 2-d array to function with **p argument. DO COMMENT ON THIS ALSO. I want to know why I am getting the error.
#include <stdio.h>
void shift(int **);
int main()
{
int i,j,a[4][5];
printf("Enter the elements of the 4X5 matrix:\n");
for(i=0;i<4;i++)
{
for(j=0;j<5;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("Entered Matrix:\n");
for(i=0;i<4;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n");
shift(a);
printf("The new array is:\n");
for(i=0;i<4;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
void shift(int **p)
{
int i;
for(i=0;i<4;i++)
{
int temp[2] = {**(p+i),*(*(p+i)+1)};
*(*(p+i)+0) = *(*(p+i)+2);
*(*(p+i)+1) = *(*(p+i)+3);
*(*(p+i)+2) = *(*(p+i)+4);
*(*(p+i)+3) = temp[0];
*(*(p+i)+4) = temp[1];
}
}
Expected Result - Rotated Array
Actual Result - Segmentation Fault(Core Dumped)
Accessing the array elements of a 2D array like that only works for 2D arrays. Instead of declaring it like this:
void shift(int **p)
You should change it to this:
void shift(int p[4][5])
And the same for the prototype of the function. Click here for a demo.

Why this program stops working at runtime?

It successfully compiles.
But at running on getting values of matrix it crashes stops working.
#include <stdio.h>
void getmat(int mat[100][100],int m,int n);
void matmul(int mat1[100][100],int mat2[100][100],int m1,int n1,int m2,int
n2,int matmul[100][100]);
void printmat(int matmul[100][100],int m,int n);
int main(void)
{
int m1,n1,m2,n2;
printf("Enter the dimensions of matrix1: ");
scanf("%d %d",&m1,&n1);
printf("Enter the dimensions of matrix2: ");
scanf("%d %d",&m2,&n2);
int mat1[m1][n1];
int mat2[m2][n2];
int matmul1[m1][n2];
int matmul2[m2][n1];
printf("For the values of matrix 1\n");
getmat(mat1,m1,n1);
printf("For the values of matrix 2\n");
getmat(mat2,m2,n2);
if(n1==m2)
{
printf("Mat1 x Mat2 is possible.");
matmul(mat1,mat2,m1,n1,m2,n2,matmul1);
printf("Mat1 x Mat2 :\n");
printmat(matmul1,m1,n2);
}
else
printf("Mat1 x Mat2 is not possible.\n");
if(n2==m1)
{
printf("Mat2 x Mat1 is possible.");
matmul(mat2,mat1,m2,n2,m1,n1,matmul2);
printf("Mat2 x Mat1 :\n");
printmat(matmul2,m2,n1);
}
else
printf("Mat2 x Mat1 is not possible.\n");
return 0;
}
void printmat(int matmul[100][100],int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
printf("%3d ",matmul[i][j]);
}
printf("\n");
}
}
void getmat(int mat[100][100],int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
printf("Enter element of %dx%d: ",i+1,j+1);
scanf("%d",&mat[i][j]);
}
}
}
void matmul(int mat1[100][100],int mat2[100][100],int m1,int n1,int m2,int
n2,int matmul[100][100])
{
int i,j,k;
for(i=0;i<m1;i++)
{
for(j=0;j<n2;j++)
{
matmul[i][j]=0;
for(k=0;k<m2;k++)
{
matmul[i][j]+=mat1[i][k]*mat2[k][j];
}
}
}
}
Help making any changes or optimizing this code.
Also another way to this.
This error shows up at running a half
Use a Debugger
Also, all your functions are written to take a 100x100 matricies.
But you declare your matricies to have variable sizes:
int mat1[m1][n1];
int mat2[m2][n2];
int matmul1[m1][n2];
int matmul2[m2][n1];
When you pass a 3x3 matrix to a function that is expecting a 100x100 matrix, you will definitely have a bad time.
I see that you are setting up your arrays with variable sizes. You should really set it up as a very large array or use malloc to set up the array properly. When you call the processing routines, pass the arrays as pointers and use the sizes as arguments in order to set up your references. You should note that myarray[i, j] is the equivalent of a single valued array using i*rowsize + j. When you define your array in the subroutines as [100, 100], it will go to [i*100 + j] which is outside the bounds of your actual array.
This causes the program to crash.
Once you actually calculate everything properly, it should work.

Passing arrays into functions, file.exe stopped working

I am a complete beginner in C and I am practicing passing arrays into functions. I wrote a program to take a two dimensional array as input and find sum of the individual columns.
And when I compiled the program I got no errors, but once I run it, I get a dialogue box saying "untitled5.exe stopped working" where untitled5 is the file name.
I got this error quite a few times. I have used both dev c++ and codeblocks to compile my program, so what is the reason for this? Is this a problem with my code or with my compiler or with my laptop?
#include<stdio.h>
void summation (int arr[][5], int size);
int main()
{
int n,arr[n][5],sum,i,j;
printf("enter the number of rows");
scanf("%d",&n);
for (i=0;i<n;i++)
{
for (j=0;j<5;j++)
{
printf("%d,%d th element is",i,j);
scanf("%d",&arr[i][j]);
}
}
summation (arr,5);
return 0;
}
void summation (int arr[][5], int size)
{
int i,j,s=0;
for(j=0;j<5;j++)
{
for (i=0;i<5;i++)
{
s=s+arr[i][j];
}
printf("%d",s);
}
}
In main() you are using i to index the first dimension of the array. In summation() you are using i to index the second dimension of the array. I think that you are going beyond the end of the first dimension inside summation() when main() does not fill up that much of the array (e.g., when you enter 2 for the number of rows).
I think you want
summation (arr,5);
And, inside summation():
for (i=0;i<size;i++)
{
s=s+arr[i][j];
}
#include<stdio.h>
void summation (int arr[][5], int size, int rows);
int main()
{
int n, sum, i, j;
printf("enter the number of rows");
scanf("%d",&n);
int arr[n][5];
for (i=0;i<n;i++)
{
for (j=0;j<5;j++)
{
printf("%d,%d th element is",i,j);
scanf("%d",&arr[i][j]);
}
}
summation (arr, 5, n);
return 0;
}
void summation (int arr[][5], int size, int rows)
{
int i,j,s=0;
for(i=0;i<rows;j++)
{
for (j=0;i<size;i++)
{
s=s+arr[i][j];
}
}
printf("%d",s);
}
So first off I moved your array declaration to after you have initialized n and made it equal to something.
Then your next problem was you were probably going out of bounds in your summation function. You always have 5 columns in your 2darray, but you can have a different amount of rows. Pass the amount of rows, n, into the function summation to make sure you don't go out of bounds.

Creating a function for a random number 2D array

So, I have this code which I need to turn into a function:
int main(void) {
int i=0,seed;
printf("\n\nEnter seed integer value: ");
scanf("%d", &seed);
printf("\nSeed value is:%d\n\n",seed);
srand(seed);
int a[5][5];
int x,y;
printf("Matrix A:\n");
for(x=0;x<5;x++) {
for(y=0;y<5;y++) {
a[x][y] = rand() %51 + (-25);
printf("%d ",a[x][y]); }
printf("\n"); }
printf("\n\n");
So basically, it produces a 2D 5x5 array of random numbers. This works fine, however my next task is applying a function to this code, with the function name of:
void generate_matrices(int a[5][5])
I have tried multiple times, the closest I got to a successful code was:
#include <stdio.h>
#include <stdlib.h>
void generate_matrices(int a[5][5]);
int main(void) {
int a, seed;
printf("\n\nEnter seed integer value: ");
scanf("%d", &seed);
srand(seed);
printf("\nSeed value is:%d\n\n",seed);
generate_matrices(a);
return 0;
}
void generate_matrices(int a[5][5]) {
int y,z;
printf("Matrix A:\n");
for(y=0;y<5;y++) {
for(z=0;z<5;z++) {
a[y][z] = rand() %51 + (-25); }
printf("%d ",a[y][z]); }
printf("\n");
}
But this returns the error, "expected 'int(*)[5]' but arguement is of type 'int'.
All/any help is muchly appreciated. To be fair on my part, I have done 90% of the code. This is the only bit I need help with so that I can apply this to the rest of my code.
Cheers!
You have declared a as a single integer on this line int a, seed;
When you call the function with generate_matrices(a); you are passing a single integer instead of a pointer to an array.
Change your declaration line to int a[5][5], seed;
generate_matrices(a); will pass a pointer to the first element in your 5 * 5 array, to the function.
You should really print the results in main and not in the function, then you will know that the array has been modified and is available for use in the body of your program.
You have used unconventional placement of braces '}' and this makes it harder to see what belongs in each part of your for loops.
You have the print statements in the wrong places - as a result only part of the matrix is printed.
This is what it should be (just the results - in main):
printf("Matrix\n ");
for (y = 0; y < 5; y++) {
for (z = 0; z < 5; z++) {
printf("%d\t ", a[y][z]);
}
printf("\n");
}
If you use int a[5][5] and call the function with generate_matrices(a);
a function void generate_matrices(int a[5][5]) {...} compiles without error
#include<stdio.h>
#include<stdlib.h>
void modify(int b[5][5]);
int main()
{
srand(4562);
int i,j,arr[5][5];
modify(arr);
for(i=0;i<5;i++){
for(j=0;j<5;j++){
printf("%d ",arr[i][j]=rand() %51 + (-26)); }
}
return 0;
}
void modify(int b[5][5])
{
int i,j;
for(i=0;i<5;i++) {
for(j=0;j<5;j++) {
b[i][j]; }
}
}
So this is the closest I have come to completing it. It produces the number of elements I want, also within the range I want. However its not producing the 5x5 grid I need. Where have I gone wrong?
EDIT: I'm not going for neatness at the moment, I just want to get the program working how I want it too and then i'll neaten it up.
EDIT 2: Never mind, realised what I didn't include. Its fine now. Thanks for the help.

Resources