I am trying to code for matrix multiplication of square matrices and it will keep giving Segmentation fault after every few entires on several trials.
I looked up different question on the site and tried few ways around with two following codes.
Also, Why do we need the pointers to "pointer to a pointer" as given by int **mat1, **mat2 etc. ? I don't know why this is to be done but I saw it in some answer itself.
Code 1
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*sizeof(int));
for(x=0;x<n;x++)
{
mat1[x]=(int*)malloc(n*sizeof(int));
}
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*sizeof(int));
for(y=0;y<n;y++)
{
mat2[y]=(int*)malloc(m*sizeof(int));
}
//inpur matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*sizeof(int));
for(z=0;z<m;z++)
mult[z]=(int*)malloc(m*sizeof(int));
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}
Code 2:
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*n*sizeof(int));
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*m*sizeof(int));
//input matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*m*sizeof(int));
// Mx multiplicatn
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}
I have been trying to execute code 2 and then, code2 . Both end up giving seg faults after few entires.
The int ** type is what is called a ragged array. You create a ragged array by first allocating a "spine" array, which contains pointers to each of the "ribs". When you reference matrix[x][y], you're dereferencing the pointer at index x in the "spine", and then getting the element at index "y" in the "rib". Here's a nice diagram illustrating this structure:
You can read comp.lang.c FAQ list ยท Question 6.16: How can I dynamically allocate a multidimensional array? (also the source of the image above) for more information.
Another option is to actually allocate a 2D array for your matrix (my preferred method). This requires a compiler with support for some C99 constructs, but all the major compilers except the Microsoft C compiler (e.g. gcc and clang) seem to support this by default. Here's an example:
int (*matrix)[colCount] = (int(*)[colCount]) malloc(sizeof(int)*rowCount*colCount);
The weird syntax above is how you declare a pointer to an array in C. The parenthesis around *matrix are needed to disambiguate it from declaring from an array of pointers. You don't need to cast the result of malloc in C, so equivalently:
int (*matrix)[colCount] = malloc(sizeof(int)*rowCount*colCount);
This allocates a single block of memory for the matrix, and since the compiler knows the length of each row (i.e. colCount), it can insert the math to calculate the proper address for any 2D reference. For example, matrix[x][y] is equivalent to ((int*)matrix)[x*colCount+y].
I prefer allocating a 2D array because you can do all of the allocation in one line, whereas with the ragged array you have to set the pointer to each row individually, which usually requires another couple lines for a loop.
As for your segfault, this line looks suspicious:
int **mat1 = (int**)malloc(n*sizeof(int));
Since mat1 is type int**, each entry in mat1 should be an int*. However, your malloc is using sizeof(int) to allocate the memory for the entries! Try this instead:
int **mat1 = (int**)malloc(n*sizeof(int*));
Assuming you're on a 64-bit system, sizeof(int) is probably 4 (bytes), whereas sizeof(int*) should be 8 (bytes). That means you're currently allocating half as much memory as you need, which means bad thing will happen when you access the entries in the second half of that array. Using the correct size (sizeof(int*)) should fix this.
(There might be other problems too, but that's the one that stood out at first glance.)
Related
I am trying to sort an array of structs (A SJF Scheduler). I am using the qsort library function to sort the structs in increasing order according to the attribute bursttime. However, the output is not correct. I've checked some SO questions about the same but they served no use.
struct job
{
int jobno;
int bursttime;
};
typedef struct job job_t;
int mycompare(const void* first, const void* second)
{
int fb = ((job_t*)first)->bursttime;
int sb = ((job_t*)second)->bursttime;
return (fb - sb);
}
int main()
{
int n;
printf("Enter number of jobs: ");
scanf("%d", &n);
job_t* arr = (job_t*)malloc(sizeof(job_t) * n);
for(int i = 1; i <= n; ++i)
{
printf("Enter Burst time for Job#%d: ",i);
scanf("%d", &(arr[i].bursttime));
arr[i].jobno = i;
}
printf("\n");
printf("Order of the Jobs before sort:\n");
for(int i = 1; i <= n; ++i)
{
printf("%d\t", arr[i].jobno);
}
qsort(arr, n, sizeof(job_t), mycompare);
printf("\n");
printf("Order of the Jobs after sort:\n");
for(int i = 1; i <= n; ++i)
{
printf("%d\t", arr[i].jobno);
}
printf("\n");
printf("\n");
return 0;
}
This is my inputfile:
4
7
2
9
4
The output I'm getting is:
Order of the Jobs before sort:
1 2 3 4
Order of the Jobs after sort:
2 1 3 4
The expected order should be: 2,4,1,3. Am I missing anything?
At least this problem
for(int i = 1; i <= n; ++i) // bad
Use zero base indexing.
for(int i = 0; i < n; ++i)
You could change the indexing scheme to start from zero, as others have suggested, and this would certainly be the idiomatic way to do it.
But if you want to use 1-based indexing, you'll need to allocate an extra place in the array (position 0 that will never be used):
job_t* arr = (job_t*)malloc(sizeof(job_t) * (n + 1));
Then you'll need to start your sort at position 1 in the array:
qsort(&arr[1], n, sizeof(job_t), mycompare);
And, of course, you'll have to write your code to index from 1 -- but you've already done that.
The problem is that so many standard functions in C use zero-based indexing that doing anything else is inexpressive. That's a bigger problem than wasting one array position. But, for better or worse, I've had to convert to C a load of code from Fortran, so I've gotten used to working both ways.
Hi i need to check if the array is symmetry or not. i have a function that takes in a two-dimensional array of integer numbers M and the array sizes for rows and columns as parameters, and returns 1 if M is symmetric or 0 otherwise. I tried many times but the output will be either yes to non-symmetric array or no to symmetric array
Here is my code:
#include <stdio.h>
#define SIZE 10
#define INIT_VALUE -1
int symmetry2D(int M[][SIZE], int rowSize, int colSize);
int main()
{
int M[SIZE][SIZE], i, j, result = INIT_VALUE;
int rowSize, colSize;
printf("Enter the array size (rowSize, colSize): \n");
scanf("%d %d", &rowSize, &colSize);
printf("Enter the matrix (%dx%d): \n", rowSize, colSize);
for (i = 0; i < rowSize; i++)
for (j = 0; j < colSize; j++)
scanf("%d", &M[i][j]);
result = symmetry2D(M, rowSize, colSize);
if (result == 1)
printf("symmetry2D(): No\n");
else if (result == 0)
printf("symmetry2D(): Yes\n");
else
printf("Error\n");
return 0;
}
int symmetry2D(int M[][SIZE], int rowSize, int colSize)
{
int h, k, temp;
int result;
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
M[h][k] = M[k][h];
}
}
result = 0;
for (h = 0; h < rowSize && result; h++)
{
for (k = 0; k < colSize; k++)
{
//if it is not equal to its transpose
if (M[h][k] != M[h][k])
{
result = 1;
break;
}
}
}
if (result == 0)
{
for (h = 0; h < rowSize; h++)
{
for (k = 0; k < colSize; k++)
{
return result = 0;
}
}
}
else
return result = 1;
}
Several issues:
By your definition, a matrix is symmetric if and only if it is equal to its transpose. That can be the case only for square matrices, yet you accommodate non-square matrices as well, for no apparent reason.
Your symmetry2D() function contains serious logical flaws:
It makes the input symmetric via the loop that performs M[h][k] = M[k][h]
Even if it did not do so, it would never find the input non-symmetric, because its test for that is if (M[h][k] != M[h][k]), which must always fail.
It's unclear what you think the if/else and loop nest at the end of symmetry2D() are achieving for you, but provided that rowSize and colSize are both greater than zero, the actual effect of the whole construct is the same as a simple return result;.
It looks like the idea might have been to create an array containing the transpose of the input, and then compare the input to that. That would have worked, despite being rather grotesquely inefficient, but you never in fact create that separate array for the transpose. If you're going to test without creating the transpose -- which you should -- then
Do not modify the input array (so remove the first loop nest altogether).
Get your indexing right for the symmetry comparisons: M[h][k] != M[k][h]
For best efficiency, avoid redundant and needless comparisons. For example, if you have already tested the M[1][2] == M[2][1] then you do not need to test whether M[2][1] == M[1][2]. And you never need to test elements on the main diagonal. You could achieve this efficiency pretty easily with a better choice of loop bounds.
Also, if indeed the symmetry2D() function is supposed to avoid modifying the input array, consider declaring the element type for its first argument to be const int instead of plain int (but do not modify the type of the corresponding variable in main()). If you had written it that way in the first place then the compiler would have noticed the function's logically erroneous attempt to modify the array elements, and rejected the code.
I'm trying to make a program in C that transfers a 2-dimensions-array(a matrix to be particular) into a single-dimension-array. For example, if we have a matrix with L lines and C columns, it should turn into a a single line newL=L*C. Therefore, if the matrix has 3 lines and 4 columns, the new array will have 3*4=12 as its size.
The matrix should turn to this:
1 2
--> 1 2 3 4
3 4
The problem I'm facing right now, is how to assign the matrix to the array without having random values or repeated values.
The piece of code I'm concerned with, goes like this:
for(k=1;k<=t;k++)
{
for(i=1;i<=l;i++)
{
for(j=1;j<=c;j++)
{
v[k]=m[i][j];
}
}
}
k,i and j are counters of the matrix(2-dimensions-array) and the the array. two of which; i and j, are counters for the matrix and k is the array's counter. Notice that each one of them starts from 1 and goes to its size and in this size I will use 2 lines and 2 columns for the matrix therefore the array will have a size of 4(2*2).
l is the number of lines in the array.
c is the number of colunms in the array.
t is the size of the array. t=l*c
Executing the code gives me this as a return:
1 2
--> 4 4 4 4
3 4
Simply said, the piece of code will ALWAYS give the last value of the matrix to the array. So if I replace 4 with 5 in the matrix, the array will have 5 5 5 5.
EDIT:
Here is the full code to understand what I'm trying to do:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,i,j,l,k,t;
printf("Donner le nombres des lignes: ");
scanf("%d",&l);
printf("Donner le nombres des colonnes: ");
scanf("%d",&c);
int m[l][c];
t=l*c;
int v[t];
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("Donner m[%d][%d]: ",i+1,j+1);
scanf("%d",&m[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("\n\n\n\n");
for(k=1;k<=t;k++)
{
for(i=1;i<=l;i++)
{
for(j=1;j<=c;j++)
{
v[k]=m[i][j];
}
}
}
for(k=0;k<t;k++)
{
printf("%d\t",v[k]);
}
system("pause");
}
Thank you guys for the help, I found the correct way to do it.
You need not the outer loop
Array indices are zero-based in C
Thus, we have:
for(k = 0, i = 0; i < o; i++)
{
for(j = 0; j < p; j++)
{
v[k++] = m[i][j];
}
}
where o and p - dimensions of the matrix m
If we have a multidimensional array like this:
int nums[3][3];
And we have:
int all[9];
And we've got:
int a, b;
We'll reference each of the nums like this:
nums[a][b];
Now think of what the values of a and b will actually be:
for (a = 0; a < 3; a++) {
for (b = 0; b < 3; b++)
all[((a * 3) + b)] = nums[a][b];
}
This will work so long as you multiply a with the number of elements it will iterate:
int nums[5][5];
int all[25];
int a, b;
for (a = 0; a < 5; a++) {
for (b = 0; b < 5; b++)
all[((a * 5) + b)] = nums[a][b];
}
You mention your question is "how to I fix the code?" I think plenty of people have given you the correct answer. This is your code along with the corrected code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,i,j,l,k,t;
printf("Donner le nombres des lignes: ");
scanf("%d",&l);
printf("Donner le nombres des colonnes: ");
scanf("%d",&c);
int m[l][c];
t=l*c;
int v[t];
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("Donner m[%d][%d]: ",i+1,j+1);
scanf("%d",&m[i][j]);
}
}
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",m[i][j]);
}
printf("\n");
}
printf("\n\n\n\n");
/* corrected code below */
k = 0;
for(i=0;i<l;i++)
{
for(j=0;j<c;j++)
{
v[k]=m[i][j];
k++;
}
}
/* corrected code above */
for(k=0;k<t;k++)
{
printf("%d\t",v[k]);
}
system("pause");
}
As long as the new array is the correct size, something like the following should work:
k=0;
for(i=0;i<l;i++){
for(j=0;j<c;j++){
v[k]=m[i][j];
k++;
}
}
Essentially, you are traversing over the matrix (your lines and columns--as you put it) and at the same time increasing the position (k) in the new array where you want that value to be put.
This:
for(k=1;k<=t;k++)
for(i=1;i<=l;i++)
for(j=1;j<=c;j++)
v[k]=m[i][j];
does not do what you think. Think about when you first loop through the j part, you will be setting all the 0th element of v the entire time, finally the last value you set will stick (ie, the one in position 1, 1 which happens to be 4). Then you will increment k to 1 and repeat it again, resulting in all 4's. You want this:
for(i = 0; i < l; i++)
for(j = 0; j < c; j++)
v[i*l+j] = m[i][j]; // i*l + j gives you the equivelent position in a 1D vector.
Make sure your v vector is the right size ie. int v[l*c];. Also remember that in c zero indexing is used.If you really do need 1 based indexing (which you dont ...) then do this:
int k = 1;
for(i = 1; i <= l; i++)
for(j = 1; j <= c; j++)
v[k++]=m[i][j];
But remember that this will make any further operations on this vector Gross. So dont do this ....
If you just want to access the matrix elements as a single dimension array, you could declare an int pointer v:
int m[3][4];
int *v = (int*)m;
// then access for example m[1][1] as v[5]
Or, to actually copy the array, use a double for (as in the other answers), a single for like below
int vv[12];
for(i = 0; i < 12; i++)
vv[i] = m[i/4][i%4];
or just use memcpy:
memcpy(vv, m, 12*sizeof(int));
I am able to declare in a good way two matrices A and B.
But, when using the memcpy (to copy B from A), B gives me arrays of 0s.
How can I do? Is my code correct for using memcpy?
int r = 10, c = 10, i, j;
int (*MatrixA)[r];
MatrixA=malloc(c * sizeof(*MatrixA));
int (*MatrixB)[r];
MatrixB=malloc(c * sizeof(*MatrixB));
memcpy(MatrixB,MatrixA,c * sizeof(MatrixA));
for(i=1;i<r+1;i++)
{
for (j = 1; j < c+1; j++)
{
MatrixA[i][j]=j;
printf("A[%d][%d]= %d\t",i,j,MatrixA[i][j]);
}
printf("\n");
}
printf("\n");printf("\n");printf("\n");printf("\n");printf("\n");
for(i=1;i<r+1;i++)
{
for (j = 1; j < c+1; j++)
{
printf("B[%d][%d]= %d\t",i,j,MatrixB[i][j]);
}
printf("\n");
}
You copied contents before initializing MatrixA .And also you access index out of bound (r+1 evaluates 11 which is out of bound) causing UB. Do this instead -
for(i=0;i<r;i++) // i starts from 0
{
for (j =0; j < c; j++) // j from 0
{
MatrixA[i][j]=j;
printf("A[%d][%d]= %d\t",i,j,MatrixA[i][j]);
}
printf("\n");
}
memcpy(MatrixB,MatrixA,c * sizeof(*MatrixA)); // copy after setting MatrixA
for(i=0;i<r;i++) // similarly indexing starts with 0
{
for (j =0; j < c; j++)
{
printf("B[%d][%d]= %d\t",i,j,MatrixB[i][j]);
}
printf("\n");
}
Is my code correct for using memcpy?
No, your code is wrong, but that's less of a memcpy problem. You're simply doing C arrays wrong.
int r = 10, c = 10, i, j;
int (*MatrixA)[r];
MatrixA=malloc(c * sizeof(*MatrixA));
Ok, MatrixA is now a pointer to a 10-element array of integers right? So the compiler reserves memory for ten ints; however, in the malloc line, you overwrite that with a pointer to a memory region of ten times the size of a single integer. A code analysis tool will tell you that you've built a memory leak.
These mistakes continue throughout your code; you will have to understand the difference between statically allocated C arrays and dynamic allocation using malloc.
I've searched for a similar situation but have drawn a blank so I'm posting my problem here:
void mtxmulti(struct matrix mAx, struct matrix mBx, struct matrix mCx) {
printf("A * B:\n");
if ((mAx.nrows == mBx.nrows) && (mAx.ncols == mBx.ncols)) {
for (mAx.row = 0, mBx.row = 0; mAx.row < mAx.nrows, mBx.row < mBx.nrows; mAx.row++, mBx.row++) {
for (mAx.col = 0, mBx.col = 0; mAx.col < mAx.ncols, mBx.col < mBx.ncols; mAx.col++, mBx.col++) {
mCx.matrix[mCx.row][mCx.col] += mAx.matrix[mAx.row][mAx.col] * mBx.matrix[mBx.row][mAx.col];
}
}
mtxpr1t(mCx); /*If successful, prints the matrix*/
}
}
What you see here is my function to multiply two matrices together, however it crashes when I try to run it.
Other useful parts of the code:
struct matrix {
int** matrix;
int row, col, nrows, ncols;
};
int main(void) {
struct matrix A, B, C;
printf("Enter the number of rows and columns for A: ");
scanf("%d %d", &A.nrows, &A.ncols);
A.matrix = alloc(A.nrows, A.ncols); /*Allocates array*/
/*. This part of code is
. just entering the values
. of the matrix*/
printf("Enter the number of rows and columns for B: ");
scanf("%d %d", &B.nrows, &B.ncols);
A.matrix = alloc(A.nrows, A.ncols); /*Allocates array*/
/*. This part of code is
. just entering the values
. of the matrix*/
mtxmulti(A, B, C);
}
FYI: I'm being told that uninitialized local variable 'C' being used and because of this won't work. I hadn't needed to initialize matrix A and B, although I did allocate space for them as seen in the section above. The allocation looks like this:
int** all0c(struct matrix mtx) {
mtx.matrix = (int**)(malloc(mtx.nrows*sizeof(int*)));
for (mtx.row = 0; mtx.row < mtx.nrows; mtx.row++)
mtx.matrix[mtx.row] = (int*)(malloc(mtx.ncols*sizeof(int)));
return mtx.matrix;
}
EDIT
I managed to solve the issue by just printing the answer. This therefore need not have to allocate space for matrix C.
As I understand structure's fields row, col are used as counters... so you can do it, but when you initialize them and use in condition be careful:
instead
for (mAx.row = 0, mBx.row; mAx.row < mAx.nrows, mBx.row < mBx.nrows; mAx.row++, mBx.row++)
try
for (mAx.row = 0, mBx.row = 0; mAx.row < mAx.nrows && mBx.row < mBx.nrows; mAx.row++, mBx.row++)
EDIT:
And read about comma operation in the C++ references