Function changes variables not involved in the function (in c) - c

So I'm trying to make a program to row reduce a matrix (there are probably a thousand way better ways to do it but I'm trying to figure it out on my own). I have a function that is supposed to make two rows of different arrays equal. It doesn't even take the row variable as an input or have anything to do with it but for some reason after the function is called the row variable switches from whatever was put into the keyboard to 1072693248. I also just noticed a problem with the col variable where it is set to 0 the second time the for loop it is in happens. I have no clue what is causing these problems so any help would be really appreciated. I'm just going to post the entire code since I'm not sure which part is causing the problem (its probably super messy, my only coding experience is one super basic beginner course in c in university). (I put in some printfs to print row or col in different spots to try and find out where the problem was happening).
#include <stdlib.h>
void printArray(double a[][100], int rows, int columns);
void addRow(double a[][100], int columns, int rowToAdd, int rowAddedTo);
void addRowBetweenArrays(double arrayAddedTo[][100],double arrayAdded[][100], int columns, int rowToAdd, int rowAddedTo);
void multiplyRow(double a[][100], int columns, int rowMultiplied, double mupltiplyBy);
void switchRows(double a[][100], int columns, int rowOne, int rowTwo);
//void makeRowsEqual(double rowMadeEqual[][100], double madeEqualTo[][100], int rowInMadeEqualTo, int RowInMadeEqual, int columns);
void makeTwoArraysRowsEqual(double arrayMadeEqual[][100], double arrayMadeEqualTo[][100], int rowMadeEqual, int rowMadeEqualTo, int column);
int main()
{
int row, col, i, j, checkReduced, rowIsReduced = 0, focus;
double multiplyFactor;
printf("Enter the size of your array (rows columns): ");
scanf("%d %d", &row, &col);
double array[row][100];
double tempRow[1][100];
for(j = 0; j < row; j++)
{
printf("Enter row %d: ", j + 1);
for(i = 0; i < col; i++)
{
scanf("%lf", &array[j][i]);
}
printf("\n");
}
printf("\n\nUnreduced array:\n");
printArray(array, row, col);
//start the reducing
for(focus = 0; focus < row; focus++)
{
rowIsReduced = 0;
for(i = 0; i < col; i++)
{
if(i == focus)
{
i++;
}
if(array[i][focus] != 0)
{
rowIsReduced = 1;
}
}
if(rowIsReduced == 1)
{
//now start the reducing process
for(i = 0; i < row; i++)
{
printf("\n%d\n", row);
if(i == focus)
{
i++;
}
//skip the row we are focusing on
//first check if we even need to manipulate the row
if(array[i][focus] != 0)
{
if(array[focus][focus] * array[i][focus] > 0)
{
printf("\n%d\n", row);
//then check if we need to add or subtract
//make temp row equal to focus row
printf("Column before function: %d", col);
makeTwoArraysRowsEqual(tempRow, array, 1, focus, col);
// to check order: makeTwoArraysRowsEqual(double arrayMadeEqual[][100], double arrayMadeEqualTo[][100], int rowMadeEqual, int rowMadeEqualTo, int column)
printf("\nAfter make rows equal: %d\n", row);
//now multiply both rows
multiplyFactor = array[i][focus];
multiplyRow(tempRow, col, 1, multiplyFactor);//getting stuck here
//multiplyRow(double a[][100], int columns, int rowMultiplied, double mupltiplyBy);
multiplyFactor = -1 * array[focus][focus];
multiplyRow(array, col, i, multiplyFactor);
//then add them
addRowBetweenArrays(array, tempRow, col, 1, i);
printf("Made it to end of the loop");
}
else //could also use: if(array[focus][focus] * array[i][focus] < 0)
{
//then check if we need to add or subtract
//make temp row equal to focus row
//makeRowsEqual(tempRow, array, focus, 1, col); need to switch this to new format
//now multiply both rows
multiplyRow(tempRow, col, 1, array[i][focus]);
multiplyRow(array, col, i, array[focus][focus]);
//then add them
addRowBetweenArrays(array, tempRow, col, 1, i);
}
//now the rows are added so there is a zero in the focus column
//will need to check if any rows are zero and move them to the bottom, have to figure that out
//will also need to divide all the rows by their first non zero term
}
printf("\n%d\n", row);//rows are acting weird, getting to be a really big number after the first run
}
printf("Made it out of i loop");
}
}
printf("\n\Reduced array:\n");
printArray(array, row, col);
return 0;
}
void printArray(double a[][100], int rows, int columns)
{
int i, j;
for(j = 0; j < rows; j++)
{
for(i = 0; i < columns; i++)
{
printf("%6.2lf ", a[j][i]);
}
printf("\n");
}
}
void addRow(double a[][100], int columns, int rowToAdd, int rowAddedTo)
{
int i;
for(i = 0; i < columns; i++)
{
a[rowAddedTo][i] += a[rowToAdd][i];
}
return 0;
}
void addRowBetweenArrays(double arrayAddedTo[][100],double arrayAdded[][100], int columns, int rowToAdd, int rowAddedTo)
{
int i;
for(i = 0; i < columns; i++)
{
arrayAddedTo[rowAddedTo][i] += arrayAdded[rowToAdd][i];
}
}
void multiplyRow(double a[][100], int columns, int rowMultiplied, double mupltiplyBy)
{
int i;
for(i = 0; i < columns; i++)
{
a[rowMultiplied][i] *= mupltiplyBy;
}
}
void switchRows(double a[][100], int columns, int rowOne, int rowTwo)
{
int i, temp;
for(i = 0; i < columns; i++)
{
temp = a[rowOne][i];
a[rowOne][i] = a[rowTwo][i];
a[rowTwo][i] = temp;
}
}
/*
void makeRowsEqual(double rowMadeEqual[][100], double madeEqualTo[][100], int rowInMadeEqualTo, int rowInMadeEqual, int columns)
{
int i;
printf("In function: made = to: %d, made =: %d", rowInMadeEqualTo, rowInMadeEqual);
for(i = 0; i < columns; i++) {
rowMadeEqual[rowInMadeEqual][i] = madeEqualTo[rowInMadeEqualTo][i];
}
printf("\nMade equal:\n");
printArray(rowMadeEqual, 1, columns);
printf("\nMade equal to:\n");
printArray(madeEqualTo, 2, columns);
}*/
void makeTwoArraysRowsEqual(double arrayMadeEqual[][100], double arrayMadeEqualTo[][100], int rowMadeEqual, int rowMadeEqualTo, int column)
{
int i;
for(i = 0; i < column; i++) {
arrayMadeEqual[rowMadeEqual][i] = arrayMadeEqualTo[rowMadeEqualTo][i];
}
printf("Column in function: %d", column);
}
Here is a sample output:
Enter the size of your array (rows columns): 2 2
Enter row 1: 1
2
Enter row 2: 2
4
Unreduced array:
1.00 2.00
2.00 4.00
2
2
Column before function: 2Column in function: 2
After make rows equal: 1072693248
Made it to end of the loop
1072693248
1072693248
1072693248
Column before function: 0Column in function: 0
After make rows equal: 1072693248
Made it to end of the loop
1072693248
1072693248
1072693248
Column before function: 0Column in function: 0
After make rows equal: 1072693248
Made it to end of the loop
1072693248
1072693248
Process returned -1073741819 (0xC0000005) execution time : 3.808 s
Press any key to continue.
P.S. Sorry if this question is formatted poorly or something, this is my first question and I've hardly used stack overflow as of right now.

The problem is this line:
makeTwoArraysRowsEqual(tempRow, array, 1, focus, col);
The third argument is used as the row index in tempRow to copy to. tempRow is declared:
double tempRow[1][100];
Since it only has 1 row, the highest row index is 0, but you're copying to row 1, which is outside the array, resulting in undefined behavior.
You should use row index 0:
makeTwoArraysRowsEqual(tempRow, array, 0, focus, col);
You have similar problems in the calls to other functions that use tempRow. They all pass 1 when it should be 0.
It's not clear why tempRow even needs to be 2-dimensional, since it only has one row. Just make it a 1-dimensional array, and remove the row index from all the functions that use it.

Related

Got stuck in a customizable dimensional matrix operation program

`
//MATRIX INPUT
#include<stdio.h>
int main(void)
{
//declaring variables
size_t row=0;
size_t column=0;
int limit=0;
int en=0;
int mat[row][column];
//starting
printf("ENTRE THE NUMBER OF R
EPETITIONS OF MATRIX
INPUT:");
scanf("%d",&limit);
//starting loop
for(int i=0;i<=(limit-1);++i)
{
printf("\nINITIALIZED THE
MATRIX-%d...\n",i+1);
printf("\nENTER ROW
NUMBER FOR MATRIX:\n");
scanf("%d",&row);
printf("\nENTER COLUMN
NUMBER FOR MATRIX:\n");
scanf("%d",&column);
//entering the entries..
for(int j=0; j<row ;++j)
{
for(int k=0;
k<column;++k)
{
printf("ENTRY (%d,%d):",(j+1),(k+1));
scanf("%d",&mat[k][j]);
}
}
}
//starting the console output
of matrix
int v=0;
printf("Which matrix do you
want to see?\n");
scanf("%d",&v);
for(v=0; v<=limit; ++v)
{
for(int l=0; l<row; ++l)
{
for( int m=0; m<column;
++m)
{
printf("%2d", mat[m][l]);
}
}
}
return 0;
}`
I have written a program in C where the user can firstly define the number of matrices. Then, the dimension of individual matrix is defined. I have successfully proceeded to individual matrix input. But I am stuck in writing the operational codes like multiplying and adding matrices as well as to write code for showing output in matrix style.
How to fix this?
incomplete source code
Console of output
I couldn't get the part why you created an empty static array, and then changed its boundaries at least tried to change. However, I believe dynamic array allocation would serve your purpose better than static one. I implemented a 3D array that has the first index as matrices, the second index as rows of the current matrix, and the third index as columns of the current matrix. Also, fixed the display method, you have been using. However, there can be different-sized matrices for each matrix you have. Therefore, I implemented another list to keep track of the rows and columns. Lastly, I put two links at the top of the code that you can implement addition and multiplication operations by yourself. You can see the code from here:
//MATRIX INPUT
#include<stdio.h>
#include<stdlib.h>
//Add two matrices
//https://www.programmingsimplified.com/c-program-add-matrices
//Multiplying two matrices
//https://www.programiz.com/c-programming/examples/matrix-multiplication
void display_matrix(int** , int , int );
void fillWithNum(int**,int,int,int);
int main(void)
{
//declaring variables
size_t row=0;
size_t column=0;
int limit=0;
int en=0;
int ***mat;
//starting
printf("ENTRE THE NUMBER OF REPETITIONS OF MATRIX INPUT:");
scanf("%d",&limit);
mat = (int***)malloc(sizeof(int**) * limit);
//Two keep track of the rows and columns
//First index of the second dimension will be rows, and
//second index will be columns of matrices at the mat variable.
int **indexingList;
indexingList = (int**)malloc(sizeof(int*) * limit);
for(int i=0;i<limit;++i) {
indexingList = (int*) malloc(sizeof(int) * 2);
}
//starting loop
for(int i=0;i<limit;i++)
{
printf("\nINITIALIZED THE MATRIX-%d...\n",i+1);
printf("\nENTER ROW NUMBER FOR MATRIX:\n");
scanf("%d",&row);
printf("\nENTER COLUMN NUMBER FOR MATRIX:\n");
scanf("%d",&column);
mat[i] = (int**) malloc(row * sizeof(int*));
for (int j = 0;j < row;j++) {
mat[i][j] = (int*)malloc(column * sizeof(int));
}
//entering the entries..
for(int j=0;j < row;j++)
{
for(int k=0;k < column;k++)
{
printf("ENTRY (%d,%d):",(j+1),(k+1));
scanf("%d",&mat[i][j][k]);
}
}
indexingList[i][0] = row;
indexingList[i][1] = column;
}
//starting the console output of matrix
int v=1;
printf("Which matrix do you want to see?\n");
scanf("%d",&v);
//v-1 because if user want to display first matrix it should be 0, so user will enter 1
//therefore, 1-1 will give us 0 to display 0 index matrix
display_matrix(mat[v-1], indexingList[v-1][0], indexingList[v-1][1]);
//Problem at freeing memory for some purpose crash at here.
//I couldn't figure it out as well.
for(int i = 0;i < limit;i++) {
for(int j = 0;j < indexingList[i][0];j++) {
free(mat[i][j]);
}
free(mat[i]);
}
free(mat);
for(int i = 0;i < limit;i++) {
free(indexingList[i]);
}
free(indexingList);
return 0;
}
void display_matrix(int** matrix, int r, int c) {
for(int i = 0 ;i < r;i++){
for(int j = 0;j < c;j++) {
printf("%d\t",matrix[i][j]);
}
printf("\n");
}
}
//Test purpose
void fillWithNum(int** arr,int r, int c, int num) {
for (int i = 0;i<r;i++) {
for(int j = 0;j<c;j++) {
arr[i][j] = num;
}
}
}
However, this code also crashes at the end of the memory-freeing part. I couldn't figure out why, but if someone finds it out as well, I would appreciate it.

Multiply a line of a matrix by a number given

I'm supposed to multiply a certain line (I specify what line exactly in the 4th argument of the function) of a given matrix by a number.
The main function:
int main_tp05(int argc, const char *argv[]){
int mNx100[][MAXCOLS100] = {{1,2,3},{4,5,6},{7,8,9}};
multiply_matrixNx100_line_by_scalar(mNx100,3,3,1,2);
return 0;
}
I've tried to solve it like so:
void multiply_matrixNx100_line_by_scalar(int mNx100[][MAXCOLS100], int lines, int columns, int line, int scalar){
for (int i = 0; i < lines; i++) {
for (int j = 0; j < columns; j++) {
if(i == line){
printf("%d\n", mNx100[i*scalar][j] );
}
}
printf("\n");
}
}
To note that:
1- I can´t change the parameters.
2- MAXCOLS100 is a macro on the .h file. I put it with the value of 3.
3- The scalar is the number I want to multiply the line by.
I WROTE THIS CODING AND VERIFIED BY MYSELF IT WORKS SUCCESSFULLY.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j,a[5][5],b,c,d,m,n,r;
printf("Enter the number of rows and columns\n");
scanf("%d %d",&m,&n);
printf("Enter the matrix\n");
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("Enter the number to multiply the matrix\n");
scanf("%d",&b);
printf("Enter 0 to multiply row or 1 to multiply column\n");
scanf("%d",&d);
if(d==0)
{
printf("Enter the row number to be multiplied\n");
scanf("%d",&r);
for(i=r,j=1;j<=n;j++)
{
a[i][j]*=b;
}
}
else if(d==1)
{
printf("Enter the row number to be multiplied\n");
scanf("%d",&c);
for(j=c,i=1;i<=m;i++)
{
a[i][j]*=b;
}
}
printf("matrix after multiplied\n");
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
OUTPUT OF THIS CODING
I'm supposed to multiply a certain line (I specify what line exactly in the 4th argument of the function) of a given matrix by a number
Usually, "multiply a row of a matrix by a scalar" means to multiply every element of the row by a certain scalar value. That's not what the posted function does, it multiplies the index of the row by the passed argument:
void multiply_matrixNx100_line_by_scalar(int mNx100[][MAXCOLS100], int lines, int columns,
int line, int scalar) {
for (int i = 0; i < lines; i++) { // <-- Useless, the row is known
for (int j = 0; j < columns; j++) {
if(i == line){
printf("%d\n", mNx100[i*scalar][j] );
// ^^^^^^^^
}
}
printf("\n");
}
}
If the intent is to only print the modified row, the previous function could be rewritten as
void multiply_matrixNx100_line_by_scalar(int mNx100[][MAXCOLS100], int lines, int columns,
int line, int scalar) {
if (line < 0 || line >= lines)
return;
for (int j = 0; j < columns; j++) {
printf("%d\n", mNx100[line][j] * scalar);
}
printf("\n");
}
If instead the function is supposed to only modify the matrix, without printing it, we could use
mNx100[line][j] *= scalar;
Inside the loop, in place of the call to printf.

how to scan a 2d array using a function without deleting it's content

as a homework assignment, i need to scan N matrices and a user input integer, and scan if any of the matrices values contains that number
without using pointers.
as soon as i finish scanning the array and exits the function, the content of the array resets to zero, or trash if i dont init the array.
#pragma warning(disable:4996)
#include<stdio.h>
#define N 2
int exist(int matrix[][N], int elem);
void input_matrix(int matrix[][N], int size);
void main()
{
int matrix_1[][N] = { 0 }, matrix_2[][N] = { 0 }, matrix_3[][N] = { 0 };
int elem;
printf("please enter values of squared matrix:\n");
input_matrix(matrix_1[][N], N);
//(input_matrix(&matrix_2[N][N]));
// (input_matrix(&matrix_3[N][N]));
printf("please enter number to search for in the matrix:\n");
scanf("%d", &elem);
if (exist(matrix_1,elem))
//printf("exist.");//the next part of h.w to be written when input func works
}
void input_matrix(int matrix[][N], int size)//something here fishy
{
int i, j;
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
scanf("%d", &matrix[i][j]);
}
}
}
int exist(int matrix[][N], int elem)
{
int i, j;
int flag = 0;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if ((matrix[i][j]) == elem)
{
flag = 1;
break;
}
}
}
return flag;
}
Inside the main function, in the call input_matrix(matrix_1[][N], N) you pass the invalid parameter. Instead should pass the whole matrix, like input_matrix(matrix_1, N).
As noted in a comment, it will be better to declare matrix like matrix_1[N][N].

Counting pixels using recursion

I have a problem where I need to count the number of 1's in a 2D array that is randomly generated. First the user puts in the size of the 2D array through the command line arguments, and then the user puts in the coordinates to see if there are 1's in the coordinates he put in. If the coordinate happen to land in 0, it is supposed to return 0. Otherwise if the inputted coordinate lands on a 1, then I am supposed to recursively check up, top right, right, bottom right, bottom, bottom left, left, and top left.
The main problem I am having is that I don't know if I can even read in one 1 from the array. I have no idea what to put into my recursive method parameters. I have my array pointer, xcoord, ycoord which are what the user puts in and row and col which are supposed to be command line arguments.
I think everything else works, but I could be wrong. I tried this recursive formula.
if(arr[row][col] == 1)
{
recursive(arr, xcoord-1, ycoord, row, col);
blobsize = blobsize + 1;
//more recursive things down here...
}
to check up but it didn't do anything.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
int recursive(int **arr, int xcoord, int ycoord, int row, int col);//What are the arguments for the recursive function?
int main(int argc, char** argv)
{
int i;//counters
int j;//counters
int xcoord;//x coordinate input
int ycoord;//y coordinate input
//random number generator thing idk lol
srand((unsigned int)time(NULL));
int row = strtol(argv[1], NULL, 0);//ROW from command line arguments (1st number)
int col = strtol(argv[2], NULL, 0);//COL from command line arguments (2nd number)
int *arrStorage = malloc(row * col * sizeof(int));//dynamically allocating memory for 2d array
int **arr = malloc(row * sizeof(int*)); //pointer to pointer to array or whatever
//intializing array
for (i = 0; i < row; i++)
{
arr[i] = arrStorage + col * i;
}
//printing out 2d array
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
arr[i][j] = rand() % 2;
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf(" ");
//Exit the function when non number is entered
//Otherwise continue
while(1)
{
printf("Enter coordinate i,j (Non numeric to quit) \n");
if(1!=scanf("%d", &xcoord) || 1!=scanf("%d", &ycoord))
{
return 0;
}
printf("Blob size: %d\n", recursive(arr, xcoord, ycoord, row, col));
}
free(arr[0]);
free(arr);
}
int recursive(int **arr, int xcoord, int ycoord, int row, int col)
{
int blobsize = 0;
//This is outside the bounds (BASE CASE)
if(xcoord > row && ycoord > col)
{
return 0;
}
//If the selected xcoord & ycoord is 0
if(arr[xcoord][ycoord] == 0)
{
return 0;
}
else
{
if((arr[xcoord][ycoord]==1))
{
//blobsize = blobsize + 1;
//recursive(arr, xcoord - 1, ycoord, row, col);
}
else
{
}
}
return blobsize;
}
Thanks if you can help
EDIT: Fixed one critical part. Now to die over figuring out the recursion part.
OP was printing a random number, yet not assigning the number to the array.
Simply assign the value and then print.
// printf("%d\t", rand() % 2);
arr[i][j] = rand() % 2;
printf("%d\t", arr[i][j]);

2D Array elements changing after they are set

The program below is meant to print a square grid of integers based on the dimension which is inputted by the user (as part of the harvard cs50 course on edx).
The array is being initialized correctly, but when it comes to printing it out, the last column always prints incorrectly. I tried debugging by putting 2 printf statements in the innermost for loop of the init() function.
It seems that after the outermost loop runs once, the entry in the last column gets decremented by one, although it was correct just before this.
Why is this happening? Shouldn't it print correctly?
#include <stdio.h>
main()
{
void init(int dim, int arr[dim-1][dim-1]);
int dim;
printf("Enter board dimension(max 10): ");
scanf("%d", &dim);
int arr[dim-1][dim-1];
init(dim, arr);
int i,j;
for(i=0;i<dim;i++)
{
for(j=0;j<dim;j++)
{
printf("%2d ",arr[i][j]);
}
printf("\n");
}
}
void init(int dim, int arr[dim-1][dim-1])
{
int i,j,p;
for(i=0;i<dim;i++)
{
for(j=0;j<dim;j++)
{
arr[i][j] = (dim*dim-1)-i*dim-j;
}
for(p=0;p<dim;p++)
{
printf("%d ", arr[i][p]);
if(i>=1)
printf("%d ", arr[i-1][p]);
}
}
printf("\n");
if(dim%2==0)
{
arr[dim-1][dim-3] = 1;
arr[dim-1][dim-2] = 2;
}
}
EDIT: it should compile now
You define your array with a[dim - 1][dim - 1], which is one short of the desired dimension. If the user enters "4", you create a 3×3 array.
Your array is two-dimensional and of variable length. Therefore, you must pass the dimension alongside the array in functions, at least for the last dimension. You do this correctly, but the code in ´initbehaves as if the array werea[dim][dim], when it's actuallya[dim - 1][dim - 1]`.
Define the array with the actual dimension, dim and access the elements with indices 0 through dim - 1. This is usually done in a loop like this:
for (int i = 0; i < dim; i++) ...
Seeing >= or dim - 1 something similar should make you wary.
Your program now looks like this:
#include <stdio.h>
void init(int dim, int arr[dim-1][dim-1]);
void print(int dim, int arr[dim-1][dim-1]);
int main(void)
{
int dim;
printf("Enter board dimension: ");
scanf("%d", &dim);
int arr[dim][dim];
init(dim, arr);
print(dim, arr);
return 0;
}
void print(int dim, int arr[dim][dim])
{
int i,j;
for(i = 0; i < dim; i++) {
for(j = 0; j < dim; j++) {
printf("%2d ", arr[i][j]);
}
printf("\n");
}
}
void init(int dim, int arr[dim][dim])
{
int i, j;
for(i = 0; i < dim; i++) {
for(j = 0; j < dim; j++) {
int ii = dim - 1 - i;
int jj = dim - 1 - j;
arr[i][j] = ii*dim + jj;
}
}
}

Resources