I'm making a matrix multiplication calculator in C. When I run it, spews out many numbers and results in this:
57736 segmentation fault
Where did I write wrong? Here is the code I wrote:
int Mtx1row, Mtx1col, Mtx2row, Mtx2col, c, d, e;
int first[10][10], second[10][10], mult[10][10];
Get 1st Matrix row and col
printf("First Matrix: # of row and col?\n");
scanf("%d%d", &Mtx1row, &Mtx1col);
Get 2nd Matrix row and col
printf("Second Matrix: # of row and col?\n");
scanf("%d%d", &Mtx2row, &Mtx2col);
Compare 1st Matrix col vs 2nd Matrix row
if (Mtx1col != Mtx2row){
printf("Mtx1col != Mtx2row (x _ x)\n");
return 1;
}
Get elements of first matrix
printf("Enter elements of First Matrix: \n");
for (c = 0; c < Mtx1row; c++)
for (d = 0; d < Mtx1col; d++)
{
printf("\tEnter element %d%d: ", c+1, d+1);
scanf("%d", &first[c][d]);
}
Get elements of second matrix
printf("Enter elements of Second Matrix: \n");
for (c = 0; c < Mtx2row; c++)
for (d = 0; d < Mtx2col; d++)
{
printf("\tEnter element %d%d: ", c+1, d+1);
scanf("%d", &second[c][d]);
}
Multiply Matrix 1 and 2 and store into Matrix Product
for (c=0; c < Mtx2row; c++){
for (d=0; d < Mtx2col; d++){
for (e=0; e < Mtx1col; e++){
mult[c][d] += first[c][d] * second[d][e];
}
}
}
Two matrices could be multiplied if an only if
#columns of the first matrix = #rows of the second matrix.
So you need to check this before creating the 2D arrays themselves.
if(Mtx1col == Mtx2row){
//proceed creating the matrices
int first[Mtx1row][Mtx1col], second[Mtx2row][Mtx2col];
int mult[Mtx1row][Mtx2col]; // The resulting matrix is Mtx1row * Mtx2col
// You have variable length arrays(VLAs) above.
}
else{
// put the f/b code here
}
Note
Under C11, VLAs are an optional feature rather than a mandatory feature,
as they were under C99.
The term variable in variable-length array does not mean that you can
modify the length of the array after you create it. Once created, a
VLA keeps the same size. What the term variable does mean is that you
can use a variable when specifying the array dimensions when first
creating the array.
The above excerpt is from Stephen Prata's C++ Primer Plus 6th edition
At least one of your array variables mult, first, second does not provide enough memory for the accesses happening.
When Mtx2row, Mtx2col and Mtx1col have values between 0 and 10 inclusively, the memory accesses should be fine. So please check the value of these variables. As a first step you can just printf these values, better would be a programmatic check that precludes out of bounds values. Also, please check that the matrices have compatible dimensions for matrix multiplication, i.e. Mtx1col must be equal to Mtx2row.
EDIT:
Now that the shown code includes the scanf statements, I can give the following advice. Always check the return code of scanf to ensure all arguments have been parsed. You can even add an additional %c to ensure there was no extra input. In your case you also have to check if the read array indices are inside the permissible range (here 0-9).
Related
I need to populate an array of integers with an unknown number of elements. I am using a while loop to input values and exit the loop as a non integer value is entered. Outside the loop an integer j is initialized at 0 and used to address array elements inside the loop. At each round of the loop I check the value of j before and after the input value is assigned to array element v[j], then j is incremented.
Depending on the size chosen for the array in the declaration, (in the example below v[8]), index j is unexpectedly affected by the assignment itself: in the example below when j equals 11 before the assignment it becomes 2 after the assignment, thereafter messing it all up. As a result the code fails to assign the correct input values to the array.
I am surely lacking some deeper knowledge about C/C++ array management... anyone can help to to fill the gap explaining the apparently strange behaviour of my code?
#include <stdio.h>
int main()
{
int j = 0, m, v[8];
printf("Enter an integer: to finish enter x\n");
while (scanf("%d", &m))
{
printf("j before assignment:%d - ", j);
v[j] = m;
printf("j after assignment:%d - ", j);
printf("v[j] after assignment:%d\n", v[j]);
j++;
}
return 0;
}
You write beyond the array boundaries of v. To avoid this, check j in a for loop, e.g. replace while (...) with
for (j = 0; j < 8 && scanf("%d", &m) == 1; ++j) {
// ...
}
This way, the loop stops after the end of the array (v[7]) is reached.
To comment the "strange" behaviour, read about stack and stack layout, e.g. Does stack grow upward or downward?
As always, check the C tag wiki and the books list The Definitive C Book Guide and List
Task: Calculate the 25 values of the function y = ax'2 + bx + c on the interval [e, f], save them in the array Y and find the minimum and maximum values in this array.
#include <stdio.h>
#include <math.h>
int main()
{
float Y[25];
int i;
int x=3,a,b,c;
double y = a*pow(x,2)+b*x+c;
printf("a = ", b);
scanf("%d", &a);
printf("b = ", a);
scanf("%d", &b);
printf("c = ", c);
scanf("%d", &c);
for(i=0;i<25;i++)
{
printf("%f",y); //output results, not needed
x++;
}
system("pause");
}
Problems:
Cant understand how can I use "interval [e,f]" here
Cant understand how to save values to array using C libraries
Cant understand how to write/make a cycle, which will find the
minimum and maximum values
Finally, dont know what exactly i need to do to solve task
You must first ask the user for the values of a, b, c or initialize those variables, and ask for the interval values of e, f, or initialize those variables.
Now you must calculate double interval= (f - e)/25.0 so you have the interval.
Then you must have a loop for (int i=0, double x=e; i<25; i++, x += interval) and calculate each value of the function. You can choose to store the result in an array (declare one at the top) or print them directly.
Problems:
Cant understand how can I use "interval [e,f]" here
(f-e) / 25(interval steps)
Cant understand how to save values to array using C libraries
You need to use some form of loop to traverse the array and save the result of your calculation at every interval step. Something like this:
for(int i = 0; i < SIZE; i++)
// SIZE in this case 25, so you traverse from 0-24 since arrays start 0
Cant understand how to write/make a cycle, which will find the minimum and maximum values
For both cases:
traverse the array with some form of loop and check every item e.g. (again) something like this: for(int i = 0; i < SIZE; i++)
For min:
Initialize a double value(key) with the first element of your array
Loop through your array searching for elements smaller than your initial key value.
if your array at position i is smaller than key, save key = array[i];
For max:
Initialize a double value(key) with 0;
Loop through your array searching for elements bigger than your initial key value.
if your array at position i is bigger than key, save key = array[i];
Finally, dont know what exactly i need to do to solve task
Initialize your variables(yourself or through user input)
Create a function that calculates a*x^2 + b*x + c n times for every step of your interval.
Create a function for min & max that loops through your array and returns the smallest/biggest value.
Thats pretty much it. I will refrain from posting code(for now), since this looks like an assignment to me and I am confident that you can write the code with the information #Paul Ogilvie & I have provided yourself. Good Luck
#include<stdio.h>
#include<math.h>
int main()
{
double y[25];
double x,a,b,c,e,f;
int i,j=0;
printf("Enter a:",&a);
scanf("%lf",&a);
printf("Enter b:",&b);
scanf("%lf",&b);
printf("Enter c:",&c);
scanf("%lf",&c);
printf("Starting Range:",&e);
scanf("%lf",&e);
printf("Ending Range:",&f);
scanf("%lf",&f);
for(i=e;i<=f;i++)
{
y[j++]=(a*pow(i,2))+(b*i)+c;
}
printf("\nThe Maximum element in the given interval is %lf",y[j-1]);
printf("\nThe Minimum element in the given interval is %lf",y[0]);
}
Good LUCK!
I'm back again with that C question heh. So I'm trying to get the user to input a whole 2d array (size, values, everything), with VLA arrays (im using the latest compiler). Everything is fine up until I get the nested for loop, then it saves the last value into the array and ignored anything before it. I cannot seem to figure out how to fix my VLA to iterate through every element in the array and assign the value typed in by the user, all I get is it saving my last value into the whole array. Through some testing I've found that my problem is contained in my Inner loop of my nested for loop. EDIT: Through the help of Weather Vane, it was figured out that the array needs to be initialized after my x and y are saved, but now it saves my last value in the whole array and not every value typed. Here's my code snippet:
int x, y, row, col, a = 0;
//int NxM[x][y]; Moved
bool counter[10]; //I have 1 last part to code that involves this
printf("This program counts occurrences of digits 0 through 9 in an NxM
array.\n");
printf("Enter the size of the array (Row Column): ");
scanf("%d %d", &x, &y);
int NxM[x][y]; //Moved here.
for(row = 0; row < x; row++){
printf("Enter row %d: \n", a);
a++;
for(col = 0; col < y; col++){
scanf("%d ", &NxM[x][y]);//Why you only save 1 value >.<
}
}
(The reason I have my printf statement between my loops was to test where my looping problem was, and because I need my printf to look like Enter row 0 Enter row 1 etc..)
I would like to know if there is any simple way to sum two rows of a 2D array in C without using a loop. I got the following sample code in the main function
for (i = 0; i < 3; i++) {
(*A)[i] = drand48();
(*B)[i] = drand48();
}
I'm using two pointers (A and B) to an array of length 3, and after initializing them with random numbers I want to sum them in a single sentence (like a vector sum). Let C be another pointer to an array of length 3. I have tried
(*C) = (*A) + (*B);
But I'm getting an error with that. In fortran, one can do it simply by putting:
C = A + B
Assuming A, B, and C are arrays of the same length, and both A and B are initilized. Or, if we want to sum two rows of a 2Darray, we can put:
C = A(i,:) + A(j,:)
which sum the row i to the row j.
So, there's a analogous way in C??
Thaks for your help.
There are several things you should understand: First, fortran compiles a loop for you, so when its code runs it is still looping through the data. Second, an optimizer might do some work for you by "un-rolling" the loop. You could write your code that essentially unrolls a small loop, as:
for (i = 0; i < 2; i++) {
C[i][0] = A[i][0] + B[i][0];
C[i][1] = A[i][1] + B[i][1];
C[i][2] = A[i][2] + B[i][2];
}
However, the same number of adds is still executed whether you code in Fortran, Matlab (a vector oriented language) or C (with or without loop unrolling).
I got this to function.
More or less, there is an error in the sumline at the end of each line.
#include <stdio.h>
int main ()
//2D_Array. Create 2D array . Multiplication in each array slot.
//KHO2016.no4. mingw (TDM-GCC-32) . c-ansi .
{
//Declare
int a,b,c,d,sum;
int k,l,num_array[50][50];
//vaulate
jump1 :
printf ("Coordinat system Descartes\nBasically two FOR-loops.\n\n");
printf ("Plot X no. of Columns, Horizontal axis. Then Y no. of Rows, Vertical axis\n:\n");
scanf ("%d %d",&a,&b); //a = vertical , b=Horizontal.
printf ("\nPlot two no. to be multipled\n:\n");
scanf ("%d %d",&c,&d);
//calculate
for (l=0;l<b;l++) // l counts lines or on Y axis .
{for (k=0;k<a;k++) // k counts colums (on each line) .
printf ("[Y%d] [X%d] (%d * %d = %d)\t: ",l,k,c++,d,c*(d));
sum = (sum+(c*d++));
printf ("sum %d",sum);
printf ("\n");}
printf ("\n");
goto jump1;
//terminate
return 0;
}
Here one can select a coordinate,
and obtain the value of the selected coordinate.
But no sum of each line .
#include <stdio.h>
int main ()
//2D_Array.(float). Select Coordinate, and obtain slot Value .
//KHO2016.no6. mingw (TDM-GCC-32) . c-ansi .
{
//declare
int aa,c,d,p,q;
float j,ar_d[10][10];
//valuate
jump0:
printf ("Select 1, 2, 3, 4 : ");
scanf ("%d",&aa);
if (aa==1&&2&&3)
goto jump0;
//calculate
if (aa==4)
{for (c=0;c<10;c++)
for (d=0;d<10;d++)
ar_d[c][d]=(float)d/c;
for (c=0;c<10;c++)
{for (d=0;d<10;d++)
printf ("(Y%d X%d.%.1d/%.1d= %.2f) ",c,d,c,d,ar_d[c][d]);
printf ("SumLine1(%d)/(%d) = %.2f\n",c,d,j);
j=(float)d/(c+1);}
printf ("\nSelect a Coordinate : first X then Y\n");
scanf("%d%d",&p,&q);
printf ("Coordinate X[%d],Y[%d] has this value : %f\n",p,q,ar_d[q][p]);}
goto jump0;
//terminate
return 0;
}
I was trying to solve a question on 2-D matrix, but unfortunately the matrix input was giving an error. This is the code:
int arr[4][4];
int r, c;
scanf("%d", &r);
scanf("%d", &c);
int i, j;
fflush(stdin);
for(i = 0; i < r; i++)
for(j = 0; j < c; j++)
scanf("%d", &arr[i][j]);
When I run this, it takes extra input.
For example: if r = 2 and c = 2> then it takes 6 input and then hangs. What to do?
If r=2 and c=2, it executes the first 2 scanf and then the 2x2 scanf of your 2D loop.
This makes 2 + 2x2 = 6.
After the last scanf, if your program is finished, it simply closes, that's normal.
I have copied your code and tried executing it and I observed that it is showing the behaviour told by you if we are taking r and c greater than their limits. So use proper limits.
I think the problem with your code is that you've allocated a fixed amount of space for your array but allowed the user to provide an arbitrary number of inputs by making the bounds of your loop the user-provided r and cvariables. Thus if the user provides r=6 and c=6, at some point your loop will attempt to dereference arr[5][5], which is invalid since you've defined int arr[4][4];. If you want to allow the user to create as many rows and columns as they want, you should initialize arr with the user-provided input, like this:
int r,c;
scanf("%d",&r);
scanf("%d",&c);
int arr[r][c];
In your code you have simply run a loop and how much value will be scan depend on the how many loops has executed.
Suppose you take r=1,c=1.
In this condition for every "r" value c will executed single time.
So When your value will be larger than the array size that time it will give you abnormal behavior.
if you will firstly input the value of "c", and "r"after that it will behave normally.
int r, c;
scanf("%d", &r);
scanf("%d", &c);
int arr[r][c];