i wrote a program to find the determinant of a n by n matrix using recursion(laplace theorem) .
they are three functions
1)determinant() to find the determinant of n*n matrix
2)create() to dynamically allocate a n*n array
3)copy() to create n-1*n-1 minor of n*n array
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int determinant(int **a,int size,int noentry);// find determinant using recursion
int copy(int **b,int **a,int size,int noentry);//copy elements to minor
int **create(int size); // dynamically allocate a two dimensional array
int main()
{
int **a,size,i,j,y;
printf("enter the order of the determinant \n");
scanf("%d",&size);
a=create(size);
printf("enter your elements \n");
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
scanf("%d",&a[i][j]);
}
}
y=determinant(a,size,0);
printf("the determinant is %d \n",y);
return 0;
}
int determinant(int **a,int size,int noentry)
{
int i;
static int det=0;
if(size<=2)
return a[0][0]*a[1][1]-a[0][1]*a[1][0];
else
{
for(i=0;i<size;i++)
{
int **b;
b=create(size-1);
copy(b,a,size-1,i);
det= det+pow(-1,i)*a[0][i]*determinant(b,size-1,i);
}
return det;
}
}
int copy(int **b,int **a,int size,int noentry)
{
int i,j,k;
for(i=1;i<=size;i++)
{
k=0;
for(j=0;j<=size;j++)
{
if(j==noentry)
continue;
else
{
b[i-1][k]=a[i][j];
k++;
}
}
}
return size;
}
int **create(int size)
{
int **b;
if(size<=0)
{
printf("the size cannot be negative/null \n");
return NULL;
}
int i;
printf("entered the create function \n");
b=(int **)malloc(sizeof(int *)*size);
for(i=0;i<size;i++)
b[i]=(int *)malloc(size*sizeof(int));
return b;
}
the program is working correctly for 3 by 3 matrix but no for 4 by 4 matrix i can't spot the error.
First, you never free allocated bloc which is bad. You should create a destroy method to free a previously allocated matrix and call it once per create call.
Next, you pass an unused noentry parameter to determinant. It should just be: int determinant(int **a,int size);
But the cause of your error is that in determinant method, det variable is static. As you recurse in determinant, each new invocation should have its own det copy instead or sharing the same one.
TL/DR: just remove the static qualifier for det variable in determinant function.
Last advice: debugging would be easier if you allocated your matrices... matrix wise!
int **create(int size)
{
int i;
int **b;
if(size<=0)
{
printf("the size cannot be negative/null \n");
return NULL;
}
printf("entered the create function \n");
b=(int **)malloc(sizeof(int *)*size);
b[0]=(int *)malloc(size * size*sizeof(int));
for(i=1;i<size;i++)
b[i]=b[0] + i * size;
return b;
}
void destroy(int **a) {
free(a[0]);
free(a);
}
That way the whole matrix uses contiguous memory to allow to see its content easily in a debugger by watching at size² integers starting at a[0]. And as a side effect, the destroy function is damned simple.
Just to be exhaustive, the fixed determinant function becomes:
int determinant(int **a,int size)
{
int i;
int det=0;
int m1 = 1;
if(size<=2)
return a[0][0]*a[1][1]-a[0][1]*a[1][0];
else
{
for(i=0;i<size;i++)
{
int **b;
b=create(size-1);
copy(b,a,size-1,i);
det= det+m1*a[0][i]*determinant(b,size-1);
destroy(b);
m1 = - m1;
}
return det;
}
}
Related
For some Reason the Program Crashes at the Loop used to merge the two arrays in main.
though maybe this question is a foolish in one(idk it didn't allow me to post as my program is mostly code so now i am blabbering).
(Well it still doesn't so here's a Picture of a Cat
CAT )
//To make two arrays of user Defined Size and merge them in a third array
#include<stdio.h>
#include<stdlib.h>
void array(int**,int);
void ini(int**,int);
void display(int **,int);
int main()
{
int *a1,*a2,*a3,s1,s2,i,j;
printf("Enter Size of Array 1\n");
scanf("%d",&s1);
printf("Enter Size of Array 2\n");
scanf("%d",&s2);
ini(&a1,s1);
ini(&a2,s2);
ini(&a3,s1+s2);
printf("Enter Elements of Array 1\n");
array(&a1,s1);
printf("Array 1:\n");
display(&a1,s1);
printf("Enter Elements of Array 2\n");
array(&a2,s2);
printf("Array 2:\n");
display(&a2,s2);
for(i=0;i<s1;i++)
{
a3[i]=a1[i];
}
for(i=0,j=s1;i<s2&&j<s1+s2;i++,j++)
{
a3[j]=a2[i];
}
printf("Merged Array:\n");
display(&a3,s1+s2);
return 0;
}
void ini(int **a,int s)
{
*a=(int*)calloc(s,sizeof(int));
}
void array(int **a,int s)
{
int i;
for(i=0;i<s;i++)
{
printf("Enter Element at position %d\n",i+1);
scanf("%d",&a[i]);
}
}
void display(int **a,int s)
{
int i;
for(i=0;i<s;i++)
{
if(i==s-1)
printf("%d\n",a[i]);
else
printf("%d\t",a[i]);
}
}
a1, a2, and a3 is a pointer of an integer type variable, which stores the starting address of your buffer.
a1[index] is the value in the address of a1 with 'index' as the offset.
Since you were passing &a to your array() and display() function, you were passing the address of your variable into the function instead of passing the address of your buffer.
You could change your array() and display() to:
void array(int *a,int s)
{
int i;
for(i=0;i<s;i++)
{
printf("Enter Element at position %d\n",i+1);
scanf("%d", &(a[i]));
}
}
void display(int *a,int s)
{
int i;
for(i=0;i<s;i++)
{
if(i==s-1)
printf("%d\n", a[i]);
else
printf("%d\t", a[i]);
}
}
and call it like this:
array(a1,s1);
display(a1,s1);
Write a C program to convert 1D array to 2D array using pointers.
Follow the given steps to implement the above code.
Ask the user to input the number of rows ( m ) and the number of columns ( n ) of the 2D array.
So the total number of elements of 1D array = ( m * n ) elements.
Call the function input_array to store elements in 1D array.
void input_array (int *arr,int size) // size = m * n
Call the function print_array to print the elements of 1D array.
void print_array (int *arr, int size)
Call the function array_to_matrix to convert 1D array to 2D array.
void array_to_matrix(int **matrix, int *arr, int row, int col)
Call function print_matrix to print the elements of the 2D array.
void print_matrix(int **mat, int row, int col)
All functions should be called from the main(). Accessing and storing of elements in pointers should be carried out by using pointers only.
Code:
#include <stdio.h>
#include <stdlib.h>
#define max 100
void input_array (int *arr,int size);
void print_array (int *arr, int size);
void array_to_matrix(int **matrix, int *arr, int row, int col);
void print_matrix(int **matrix, int row, int col);
int main()
{
int m, n, arr[max], mat[max][max];
printf("Enter the number of rows(m):");
scanf("%d",&m);
printf("Enter the number of columns(n):");
scanf("%d",&n);
int size = m*n;
input_array (arr,size);
print_array (arr,size);
array_to_matrix(mat, arr, m, n);
print_matrix(mat, m, n);
}
void input_array (int *arr,int size)
{
int i;
for(i=0;i<size;i++)
{
printf("Enter element a[%d]",i);
scanf("%d",&arr[i]);
}
}
void print_array (int *arr, int size)
{
int i;
printf("\n 1D array is as follows : \n");
for(i=0;i<size;i++)
{
printf("%d",arr[i]);
}
}
void array_to_matrix(int **matrix, int *arr, int row, int col)
{
int i,j,k=0;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
matrix[i][j] = arr[k];
k++;
}
}
}
void print_matrix(int **matrix, int row, int col)
{
int i,j;
printf("\n 2D matrix is as follows : \n");
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
Error:
I am getting a segmentation fault. The problem I am having is related to pointer to the arrays and how to pass them to the function.
in
void main()
{
int m, n, arr[max], mat[max][max];
int size = m*n;
you compute size while m and n are not yet (possibly) initialized, so the value of size is undefined with undefined behavior
In
void array_to_matrix(int **matrix, int *arr, int row, int col)
{
int i,j,k=0;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
matrix[i][j] = arr[k];
}
}
}
the signature of the function says matrix is an array of pointers to int, but this is not compatible with your main where you use a 2D array. To be compatible :
void array_to_matrix(int (*matrix)[max], int *arr, int row, int col)
and same for print_matrix :
void print_matrix(int (*matrix)[max], int row, int col)
or if you prefer :
void array_to_matrix(int matrix[][max], int *arr, int row, int col)
void print_matrix(int matrix[][max], int row, int col)
But :
Write a C program to convert 1D array to 2D array using pointers
"2D array using pointers" is an is an abuse of language and means a 1D array of pointer to int, there is no 2D array.
In your previous version you limited the dimensions to 100, you do not have a reason to do that, just allocate the arrays in the heap.
Note also k always values 0 in array_to_matrix, so you always use arr[0]
And :
void main()
is wrong, main returns an int
I also encourage you to always check the result of scanf to be sure a valid input was used, else you works with non initialized value with an undefined behavior. When you read the number of rows and columns check there are not less than 1
In print_array to separate the print value with a space will help to make the result readable
Finaly :
#include <stdio.h>
#include <stdlib.h>
void input_array (int *arr,int size);
void print_array (int *arr, int size);
void array_to_matrix(int ** matrix, int *arr, int row, int col);
void print_matrix(int ** matrix, int row, int col);
int main()
{
int m, n, * arr, ** mat;
int size, i;
printf("Enter the number of rows(m):");
if ((scanf("%d",&m) != 1) || (m < 1)) {
puts("invalid value for rows");
return -1;
}
printf("Enter the number of columns(n):");
if ((scanf("%d",&n) != 1) || (n < 1)) {
puts("invalid value for columns");
return -1;
}
size = m*n;
if (((arr = malloc(size * sizeof(int))) == NULL) ||
((mat = malloc(m * sizeof(int))) == NULL)) {
puts("not enouh memory");
exit(-1);
}
for (i = 0; i < m; ++i) {
if ((mat[i] = malloc(n * sizeof(int))) == NULL) {
puts("not enouh memory");
exit(-1);
}
}
input_array (arr,size);
print_array (arr,size);
array_to_matrix(mat, arr, m, n);
print_matrix(mat, m, n);
/* free resources */
free(arr);
for (i = 0; i < m; ++i)
free(mat[i]);
free(mat);
return 0;
}
void input_array (int *arr,int size)
{
int i;
for(i=0;i<size;i++)
{
printf("Enter element a[%d]",i);
if (scanf("%d",&arr[i]) != 1) {
int c;
puts("invalid value, redo");
/* flush invalid value up to the end of line */
while ((c = getchar()) != '\n') {
if (c == EOF) {
puts("EOF, abort");
exit(-1);
}
}
i -= 1;
}
}
}
void print_array (int *arr, int size)
{
int i;
printf("\n 1D array is as follows : \n");
for(i=0;i<size;i++)
{
printf("%d ",arr[i]);
}
}
void array_to_matrix(int ** matrix, int *arr, int row, int col)
{
int i,j,k=0;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
matrix[i][j] = arr[k++];
}
}
}
void print_matrix(int ** matrix, int row, int col)
{
int i,j;
printf("\n 2D matrix is as follows : \n");
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf("%d ",matrix[i][j]);
}
printf("\n");
}
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -g -Wall c.c
pi#raspberrypi:/tmp $ ./a.out
Enter the number of rows(m):2
Enter the number of columns(n):aze
invalid value for columns
pi#raspberrypi:/tmp $ ./a.out
Enter the number of rows(m):-1
invalid value for rows
pi#raspberrypi:/tmp $ ./a.out
Enter the number of rows(m):2
Enter the number of columns(n):3
Enter element a[0]1
Enter element a[1]aa
invalid value, redo
Enter element a[1]2
Enter element a[2]3
Enter element a[3]4
Enter element a[4]5
Enter element a[5]6
1D array is as follows :
1 2 3 4 5 6
2D matrix is as follows :
1 2 3
4 5 6
pi#raspberrypi:/tmp $
I try to make a pascal triangle of n rows and I have to make a fucntion for allocate memory for the matrix, a function to print and free memory I think I have a lot of trouble in my code
in the function build I try to allocate the memory for the matrix and charge it i use a function full for chage the matrix, I think my principal problem is that I have an irregular matrix I don't know how to procede, maybe make an array of arrays or somthing like that could be better, sorry for my english
int main()
{
int **triangle=NULL;
int n;
printf("size of triangle");
scanf("%d",&n);
build(&triangle,n);
print(triangle,n);
return 0;
}
void build(int***triangle,int n){
*triangle=(int**)calloc(n,sizeof(int*));
int i;
for(i=0;i<n;i++){
*(triangle)[i]=(int*)calloc(i+1,sizeof(int));
}
full(*triangle,n);
}
void full(int**triangle,int n){
int i;
int j;
for(i=0;i<n;i++){
for(j=0;j<i;j++){
if(j==0){
triangle[i][j]=1;
}
else
if(j==i){
triangle[i][j]=1;
}
else
triangle[i][j]=triangle[i-1][j-1]+triangle[i-1][j];
}
}
}
void print(int **triangle,int n){
int i;
int j;
for(i=0;i<n;i++){
for(j=0;j<i;j++){
printf("%d",triangle[i][j]);
}
}
}
*(triangle)[i]=(int*)calloc(i+1,sizeof(int));
should be
(* triangle)[i]=(int*)calloc(i+1,sizeof(int));
I'm writing a code for my C programming class and stumbled upon a problem. I'm supposed to write a program which will show as an output Pascal's triangle. I'm to use 1d arrays and in each iteration make the array bigger by using realloc. The trouble is that even though the code compiles and runs when I type eg '7' (as the height of the tringle) in the 7th column there will be trash number. I have no idea why it happens. I'm a beginner in dynamic memory allocation, so please by gentle.
Here's my code:
int i,n;
printf("Give the height:\n");
scanf("%d", &n);
int *tab = (int*)malloc(sizeof(int));
int *tab2, liczba=2;
for(i=0;i<n;i++)
{
tab2=(int *)realloc(tab,i+1);
tab2[i]=&liczba;
print(tab2, i+1);
printf("\n");
}
void print(int *tab, int size)
{
int i;
for(i=0;i<size;i++) printf("%d\t", tab[i]);
}
#include <stdio.h>
#include <stdlib.h>
void print(int *tab, int size);
int main(void){
int i, j, n;
printf("Give the height:\n");
scanf("%d", &n);
int *tab = NULL;
for(i=1;i<=n;++i){
int *temp = realloc(tab, i * sizeof(*tab));
if(temp)
tab = temp;
else {
perror("realloc");
free(tab);
exit(EXIT_FAILURE);
}
tab[i-1] = (i == 1) ? 1 : 0;
for(j=i-1;j>0;--j){
tab[j] += tab[j-1];
}
print(tab, i);
}
free(tab);
return 0;
}
void print(int *tab, int size){
int i;
for(i=0;i<size;i++){
if(i)
putchar('\t');
printf("%d", tab[i]);
}
putchar('\n');
}
int main (void)
{
int i,j;
int n;
int **P;
int *d;
scanf("%d",&n);
d=(int*)malloc(sizeof(int)*(n+1));
P=(int**)malloc(sizeof(int*)*(n+1));
for(i=0;i<=n+1;i++)
P[i]=(int*)malloc(sizeof(int)*(n+1));
for(i=0;i<n+1;i++)
scanf("%d",&d[i]);
minimult(n,d,P);
order(1,n,P);
free(d);
for(i=0;i<n+1;i++)
free(P[i]);
free(P); //<----------------when execute here!!!!
return 0;
}
int minimum (int **M,int *d,int i, int j)
{
int count;
int temp,temp2;
for(count=i;count<=j-1;count++)
{
temp=M[i][count]+M[count+1][j]+d[i-1]*d[count]*d[j];
if(M[i][j]>temp||count==i)
{
M[i][j]=temp;
temp2=count;
}
}
return temp2;
}
int minimult(int n, int * d, int **P)
{
int i,j,k,diagonal;
int **M=(int**)malloc(sizeof(int*)*(n+1));
int result;
for(i=0;i<n+1;i++)
M[i]=(int*)malloc(sizeof(int)*(n+1));
for(i=1;i<=n;i++)
M[i][i]=0;
for(diagonal=1;diagonal<=n-1;diagonal++)
for(i=1;i<=n-diagonal;i++)
{
j=i+diagonal;
P[i][j]=minimum(M,d,i,j);
}
result=M[1][n];
for(i=0;i<n+1;i++)
free(M[i]);
free(M);
return result;
}
This algorithm is solving optimized matrix multiplication order.
Input was 4 2 3 4 5.
When I delete that line, it operates successfully.
What's the problem?
In your allocation loop for P[i], you loop one to many time and overwrite past the end of the allocated memory for P. Change the looping condition to i < n + 1 (or i <= n).