PS command on this program - c

In an assignment, I wrote 2 programs that do the same thing, but one of them uses threads. What I'm asked to do is to stop the programs while they are running and use the ps command to compare the two programs, the problem is that I don't know how to do this, I wanted to try stopping the programs using ^z but the programs execute so fast that I can't even do it, is there a way to do what I'm asked to do? is using functions like sleep will help me? or does it affect the results of the ps command?
Here're the programs that I wrote in case it helps and I can modify them to do what I want.
without threads:
#include <stdio.h>
int main(void) {
int mat[100][100]; // Declare the array
// Generate the values for the array
for (int row = 0; row < 100; row++) {
for (int col = 0; col < 100; col++) {
mat[row][col] = row * 5 + col / 3 + col;
}
}
// Sum up the values in the array
int sum = 0;
for (int row = 0; row < 100; row++) {
for (int col = 0; col < 100; col++) {
sum += mat[row][col];
}
}
// Print the result
printf("Sum of all values in mat: %d\n", sum);
return 0;
}
with threads:
#include <stdio.h>
#include <pthread.h>
#define NUM_THREADS 100 // Number of threads (one for each column)
#define ROWS 100 // Number of rows in the array
#define COLS 100 // Number of columns in the array
int mat[ROWS][COLS]; // Array to store the values
int sums[COLS]; // Array to store the sums for each column
// Thread function to sum up a column of the array
void* sum_column(void* arg) {
int col = (int)arg; // Column to sum up
// Sum up the values in the column
int sum = 0;
for (int row = 0; row < ROWS; row++) {
sum += mat[row][col];
}
// Store the result in the sums array
sums[col] = sum;
return NULL;
}
int main(void) {
pthread_t threads[NUM_THREADS]; // Threads
// Generate the values for the array
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
mat[row][col] = row * 5 + col / 3 + col;
}
}
// Create a thread for each column to sum it up
for (int col = 0; col < COLS; col++) {
pthread_create(&threads[col], NULL, sum_column, (void*)col);
}
// Wait for all threads to finish
for (int col = 0; col < COLS; col++) {
pthread_join(threads[col], NULL);
}
// Sum up the values in the sums array
int sum = 0;
for (int col = 0; col < COLS; col++) {
sum += sums[col];
}
// Print the result
printf("Sum of all values in mat: %d\n", sum);
return 0;
}

Related

Is it possible to take user input for a 2D array using pointer names in C?

I want to take user input for a 2D array using pointer name
Let's say I have a 2D array named arr1[3][3] and the pointer variable name is ptr1. Is it possible use scanf with the pointer variable name?
Check the code below. I am using ptr1+row+column in a nested loop
`#include <stdio.h>
int main(void)
{
int arr1[3][3];
int *ptr1 = &arr1[3][3];
for (int row = 0; row < 3; row++)
{
for (int column = 0; column < 3; column++)
{
scanf("%d", (ptr1 + row) + column);
}
}
}`
I know I could have taken input using scanf("%d", (*(arr1 + i) + j));
Thank you!
Use meaningful variables names. Who can know if i is the row or column.
You need to multiply the row by number of columns.
You want reference to the first element of the array not to the one outside the array bounds.
Always check the result of scanf.
#define ROWS 3
#define COLS 3
int main(void)
{
int arr1[ROWS][COLS];
int *ptr1 = &arr1[0][0];
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
if(scanf("%d", ptr1 + row * COLS + col) != 1)
{
/* handle error */
}
}
}
}
You can use a pointer to array. Or in this specific case if you will, a pointer to a row:
#include <stdio.h>
int main(void)
{
int arr1[3][3];
int (*ptr1)[3] = arr1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &ptr1[i][j]);
}
}
}
Using *(arr + i) etc notation is almost always bad practice, since arr[i] is more readable. There exists no reason why you shouldn't be using the ptr1[i][j] format in this case - unless you like to write unreadable code for the heck of it.
There are already good answer posted. my answer would be side note . In case if we have dynamic 2-D array, below implementation is for that
#include <stdio.h>
#include <stdlib.h>
#define rows 3
#define cols 3
int main ()
{
//allocate memory equal to [rows * cols]
int *arr = (int *) malloc (rows * cols * sizeof (int));
if (arr == NULL)
{
printf ("out of memory");
exit (0);
}
// accessing each row and its respective columns.
// index = row * NumberOfColumns + column
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
arr[i * cols + j] = rand () % 10;
}
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf ("Row[%d], Column[%d]:%d\n", i, j, arr[i * cols + j]);
}
}
free (arr);
arr = NULL;
return 0;
}

Initializing random 2D matrix with pointers in C

I want my matrix to look the following:
1 2 3
X X X
X X X
When X is a random number.
I tried the following:
void initMat(int *mat, int rows, int cols)
{
*(mat + 0) = 1;
*(mat + 1) = 2;
*(mat + 2) = 3;
for (int i = 0; i < rows * cols - 3; i++)
{
*(mat + 3) = rand() % 6;
mat++;
}
}
and I call the function:
initMat((int *)startValues, 3, 3);
When I print my matrix with the following function:
void printMat(const int *mat, int rows, int cols)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
printf("%4d", *mat);
mat++;
printf(" ");
}
printf("\n");
}
}
I get something that look like 2D array, as I actually wanted, for example:
startValues:
1 2 3
4 1 5
4 4 5
But when I try to print it with (In the same main, after the matrix was initiated)
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%4d", startValues[i][j]);
}
printf("\n");
}
I get:
VALUES:
1 2 3
3 4 1
1 5 2
Why does it happen? Why the values are different and some look the same. How should I reach each value? I tried also using the formula:
m+ cols*i + j //(in my case startValues + 3*i+j in the last loop)
But it gives me very large random numbers and I'm not really sure when do I need to use it instead of mat[i][j].
I suggest using pointer to Variable-Length Array (VLA). It makes code far more readable:
void initMat(int rows, int cols, int mat[static rows][cols])
{
mat[0][1] = 1;
mat[0][2] = 1;
mat[0][3] = 1;
for (int r = 1; r < rows; r++)
for (int c = 0; c < cols; c++)
mat[r][c] = rand() % 6;
}

ptheard not working on Ubuntu with matrix

this code works correctly on Windows, but does not give results on Ubuntu. What am I supposed to do about it ?
By the way, I use Ubuntu through a virtual machine, but I don't think it has anything to do with it.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUM_THREADS 4
#define MATRIX_SIZE 4
int matrixA[MATRIX_SIZE][MATRIX_SIZE];
int matrixB[MATRIX_SIZE][MATRIX_SIZE];
int matrixSerial[MATRIX_SIZE][MATRIX_SIZE]={0};
int matrixParallel[MATRIX_SIZE][MATRIX_SIZE]={0};
//Randomize matrix A and B
void randomizeMatrixAandMatrixB()
{
int i,j;
for(i=0; i<MATRIX_SIZE;i++)
for(j=0; j<MATRIX_SIZE;j++)
{
matrixA[i][j]=rand() % 10;
matrixB[i][j]=rand() % 10;
}
}
//this void is Matrix2D
void printMatrix2D(int mat2D[MATRIX_SIZE][MATRIX_SIZE])
{
int i, j;
for (i = 0; i < MATRIX_SIZE; i++)
{
for (j = 0; j < MATRIX_SIZE; j++)
{
printf("%d ", mat2D[i][j]);
}
printf("\n");
}
printf("\n");
}
//I created this here serailMatrix
void serialMatrixMultiplication()
{
int row, column,i;
for (row = 0; row < MATRIX_SIZE; row++)
for (column = 0; column < MATRIX_SIZE; column++)
for (i = 0; i < MATRIX_SIZE; i++)
matrixSerial[row][column] += matrixA[row][i] * matrixB[i][column];
}
//int step for multiplyMatrix
int step_i = 0;
void *multiplyMatrix(void*arg )
{
int core=step_i++;
int row, column,i;
for (row = core * MATRIX_SIZE / 4; row < (core + 1) * MATRIX_SIZE / 4; row++){
for (column = 0; column < MATRIX_SIZE; column++){
for (i = 0; i < MATRIX_SIZE; i++) {
matrixParallel[row][column] += matrixA[row][i] * matrixB[i][column];
}
}
}
pthread_exit(NULL);
}
//void paraleleling
void parallelMatrixMultiplication()
{
pthread_t *thread;
int i;
for (i = 0; i < NUM_THREADS; i++) {
int* p;
thread=malloc(sizeof(pthread_t));
pthread_create(thread, NULL, multiplyMatrix, (void*)(p));
}
}
int main (int argc, char *argv[])
{
srand(time(0));
//Randomize
randomizeMatrixAandMatrixB();
printf("Matrix A\n");
printMatrix2D(matrixA);
printf("Matrix B\n");
printMatrix2D(matrixB);
//Serial Matrix Multiplication
serialMatrixMultiplication();
printf("Serial Multiplication\n");
printMatrix2D(matrixSerial);
//Parallel Matrix Multiplication
parallelMatrixMultiplication();
printMatrix2D(matrixParallel);
return 0;
}
What should I do to run these codes in the virtual machine? Where is my mistake in the line of code? Since it works fine on Windows, not on linux, it shows the remaining values as 0 from the first line. For example, when we divide it into 4 threads on a 4x4 matrix, the first row looks like this starting from 0. I guess it's not running threads
For Example:
Serial Multiplaction
144 255 1 2
15 18 5 4
125 14 52 46
14 5 1 3
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
You were lucky it works on windows.
What is missing in you code is synchronisation.
You must wait for threads to finish before displaying the result. You can easily do this with pthread_join
//void paraleleling
void parallelMatrixMultiplication()
{
pthread_t threads[NUM_THREADS];
int params[NUM_THREADS];
int i;
for (i = 0; i < NUM_THREADS; i++) {
params[i] = i;
pthread_create(threads+i, NULL, multiplyMatrix, &params[i]);
}
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
}
As you can see, I also changed the argument given to multiplyMatrix to avoid using step_i: In main thread, an array containing the parameters is prepared.
//int step for multiplyMatrix
void *multiplyMatrix(void*arg )
{
int core=*(int*)arg;
int row, column,i;
for (row = core * MATRIX_SIZE / 4; row < (core + 1) * MATRIX_SIZE / 4; row++){
for (column = 0; column < MATRIX_SIZE; column++){
for (i = 0; i < MATRIX_SIZE; i++) {
matrixParallel[row][column] += matrixA[row][i] * matrixB[i][column];
}
}
}
pthread_exit(NULL);
}
One last thing: if two different threads could modify the same cell in matrixParallel, it would be a good idea to add some mutex.
parallelMatrixMultiplication() kicks off the processing threads then goes straight into printMatrix2D(). You are not waiting for the threads to finish.
You have a memory leak because you are reusing the thread variable in parallelMatrixMultiplication(). You call malloc() but not free().

How can I keep my program from getting this segmentation fault (core dumped)?

I have a program that is getting a segmentation fault. The program is a magic square program and asks users for the size of a square (a matrix) and then for the numbers of the square by row. I am using a pointer to point to the array in the declareArray function to reference where it is declared in the main function. I want to keep the pointer in order to practice using them, even though I know I can make the program work without pointers. I think the pointer is the problem here but I cant find what I am doing wrong with it.
here is the code:
int main(void)
{
int *arr[SIZE][SIZE] = "\0";
declareArray(&arr);
declareArray();
return 0;
}
//main logic
int declareArray(int *arr[SIZE][SIZE])
{
//variables
int rowNumber = 0;
int dimension = 0;
//int arr[SIZE][SIZE] = {0};
int row, col;
int sum, sum1, sum2;
int flag = 0;
//ask for input of squares
printf("Please enter the dimension of the square: ");
//makes sure the size is between 1 and 15 for the dimension of the square
if(scanf("%d", &dimension) != 1 || dimension >= 15 || dimension < 1)
{
printf("invalid input\n");
return 1;
}
//enter the data
//array rows
for(row = 0; row < dimension; ++row)
{
printf("Please enter the data for row %d: ", ++rowNumber);
//array columns
for(col = 0; col < dimension; ++col)
{
//store the user input
scanf("%2d", &*arr[row][col]);
}
}
printf("\n");
printf("Here is the square");
printf("\n");
//print the square
//array rows
for(row = 0; row < dimension; ++row)
{
//array columns
for(col = 0; col < dimension; ++col)
{
printf("%d", *arr[row][col]);
}
printf("\n");
}
//Checks Sum of diagonal elements
sum = 0;
for (row = 0; row < dimension; row++) {
for (col = 0; col < dimension; col++) {
if (row == col)
sum = sum + *arr[row][col];
}
}
//Checks Sum of Rows
for (row = 0; row < dimension; row++) {
sum1 = 0;
for (col = 0; col < dimension; col++) {
sum1 = sum1 + *arr[row][col];
}
if (sum == sum1)
flag = 1;
else {
flag = 0;
break;
}
}
//Checks sum of Columns
for (row = 0; row < dimension; row++) {
sum2 = 0;
for (col = 0; col < dimension; col++) {
sum2 = sum2 + *arr[col][row];
}
if (sum == sum2)
flag = 1;
else {
flag = 0;
break;
}
}
//if the sums match, it will print a success message with the constant
//if the sums dont match, a fail message will appear
if (flag == 1)
printf("\nTHE SQUARE IS A MAGIC SQUARE WITH A CONSTANT OF %d \n", sum);
else
printf("\nThe Square is not a magic square \n");
return 0;
}
I can see few issues here
int *arr[SIZE][SIZE] = "\0"; // this wont compile
declareArray(&arr); // needless
declareArray();
---
int arr[SIZE][SIZE] = {};
declareArray(arr);
//declareArray();
Declare function
int declareArray(int *arr[SIZE][SIZE]) // because function call changed
---
int declareArray(int arr[SIZE][SIZE])
finally in printf and scanf remove the * operator not needed anymore
as in
scanf("%2d", &*arr[row][col]); // remove *
---
scanf("%2d", &arr[row][col]);
printf("%d", *arr[row][col]); // remove *
---
printf("%d", arr[row][col]);
sum = sum + *arr[row][col]; // remove *
---
sum = sum + arr[row][col];
Note that when you declare an array, the name of the array is a pointer to the first element of the array:
&arr[0] == arr.
The argument passed to the declareArray function is an array of pointers to integers, therefore the space needed for the pointers was allocated yet the space for the actual ints was not, so when you are trying to scan an integer to the address pointed to by arr[row][col], you are trying to write to the address that it holds, 0 in your case , and address 0 is most likely out of the data segment, hence the segment_fault.
What should you do then?
Allocate the space needed with malloc(), assign the address returned to arr[row][col] and then scanf() as shown below, or alternatively, and quite simpler and better use an int array and simply assign the integer to arr[row][col] as shown in the answer above
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15
int declareArray(int * arr[SIZE][SIZE]);
int main(void)
{
int * arr[SIZE][SIZE] = {0};
declareArray(arr);
return 0;
}
//main logic
int declareArray(int * arr[SIZE][SIZE])
{
//variables
int rowNumber = 0;
int dimension = 0;
int row, col;
int sum, sum1, sum2;
int flag = 0;
int * myVal;
//ask for input of squares
printf("Please enter the dimension of the square: ");
//makes sure the size is between 1 and 15 for the dimension of the square
if(scanf("%d", &dimension) != 1 || dimension >= 15 || dimension < 1)
{
printf("invalid input\n");
return 1;
}
//enter the data
//array rows
for(row = 0; row < dimension; ++row)
{
printf("Please enter the data for row %d: ", ++rowNumber);
//array columns
for(col = 0; col < dimension; ++col)
{
printf("insert data to row %d col %d: ", rowNumber, col+1);
arr[row][col] = (int *) malloc(sizeof(int));
scanf("%2d", arr[row][col] );
}
}
printf("\n");
printf("Here is the square");
printf("\n");
//print the square
//array rows
for(row = 0; row < dimension; ++row)
{
//array columns
for(col = 0; col < dimension; ++col)
{
printf("%d", *arr[row][col]);
}
printf("\n");
}
//Checks Sum of diagonal elements
sum = 0;
for (row = 0; row < dimension; row++) {
for (col = 0; col < dimension; col++) {
if (row == col)
sum = sum + *arr[row][col];
}
}
//Checks Sum of Rows
for (row = 0; row < dimension; row++) {
sum1 = 0;
for (col = 0; col < dimension; col++) {
sum1 = sum1 + *arr[row][col];
}
if (sum == sum1)
flag = 1;
else {
flag = 0;
break;
}
}
//Checks sum of Columns
for (row = 0; row < dimension; row++) {
sum2 = 0;
for (col = 0; col < dimension; col++) {
sum2 = sum2 + *arr[col][row];
}
if (sum == sum2)
flag = 1;
else {
flag = 0;
break;
}
}
//if the sums match, it will print a success message with the constant
//if the sums dont match, a fail message will appear
if (flag == 1)
printf("\nTHE SQUARE IS A MAGIC SQUARE WITH A CONSTANT OF %d \n", sum);
else
printf("\nThe Square is not a magic square \n");
return 0;
}

Finding Duplicate value in 2d array 3x3 magic Square

Im trying to create a 2D array 3x3 square.
Calculation and checking for it is done.
Right now, am trying to prevent repeated numbers from happening in the 2d array.
I tried using a for loop to brute force but cygwin compiles gives me error
Below is my code.
How do i go about checking 2d array?
#include <stdio.h> /* printf */
/*Preprocessor*/
/*set N constant 3*/
#define N 3
typedef enum {false,true}
bool;
int main()
{
/*initialize size to 3*/
int size =3;
int sum, sum1, sum2,array[N][N];
int row, col = 0;
int i, j, duplicate =0;
/* variable to
indicate process reached*/
int checkf =0;
/*input into the array of an array*/
for(row =0; row <size; row++)
{
for(col =0; col < size; col++)
{
scanf("%d", &array[row][col]);
}
}
**/*check for repeated values*/
for(row =0; row<9; row++)
{
for(col=0; col <9; col++)
{
if(array==array[row][col])
}
}**
/*Diagonal*/
/*sum of diagonal from the left
equals to sum of diagonal
from the right */
/*initialize sum2 to 0*/
sum2 =0;
/*check if row less than 3*/
for(row=0; row< size; row++)
{
/*check if col less than 3*/
for(col=0;col<size; col++)
{
/*number of row
equals number of col*/
if(row == col)
{
/*addition*/
sum2 = sum2 + array[row][col];
}
}
}
/*row*/
/*check if row less than 3*/
for(row=0; row < size; row++)
{
/*initialize sum */
sum = 0;
/*check if col less than 3*/
for(col=0; col <size; col++)
{
/*addition of numbers*/
sum = sum + array[row][col];
}
/*check if all additions
adds up to same sum*/
if(sum2 == sum)
{
/*a flag or check to print*/
checkf =1;
}
else
{
/*a flag or check to print*/
checkf =0;
break;
}
}
/*Columns*/
/*check if row less than 3*/
for(row = 0; row < size; row++)
{
/*initialize sum */
sum1 =0;
/*check if col less than 3*/
for(col = 0; col < size; col++)
{
/*addition*/
sum1 = sum1 + array[col][row];
}
/*sum of diagonal equals
sum of columns*/
if(sum == sum1)
{
/*a flag or check to print*/
checkf =1;
}
else
{
/*a flag or check to print*/
checkf =0;
break;
}
}
/*if statement is true
prints and display*/
if(checkf ==1)
{
printf("This is a magic square.\n");
}
else
{
/*print and display*/
printf("This is not a magic square.\n");
}
return 0;
}
If you had a flat, one-dimensional array (of fixed size N, say), you would check all elements against every element to its left:
int unique1d(int array[N])
{
int i, j;
for(i = 1; i < N*N; i++) {
for(j = 0; j < i; j++) {
if (array[i] == array[j]) return 0;
}
}
return 1;
}
You can do the same for a two-dimensional array, when you "flatten" the indices first. Say you enumerate the cells of your 3×3 grid with "flat" indices like so:
0 1 2
3 4 5
6 7 8
Then you get:
flat = row * N + col;
and, conversely:
row = flat / N; // truncating int division gives row
col = flat % N; // remainder gives column
So a function that tests whether there are duplicates in your N×N grid would look like this:
int unique(int array[N][N])
{
int i, j;
for(i = 1; i < N*N; i++) {
for(j = 0; j < i; j++) {
if (array[i / 3][i % 3] == array[j / 3][j % 3]) return 0;
}
}
return 1;
}
I've made that into a separate function, because it makes the code clearer. Not how you don't need a separate flag and a break. You can return the result explicitly as soon as you have found it. (Also, the break would have to break out of a nested loop, but the break keyword in C just jumps out of the inner loop.)
(The rest of your code that checks whether the square is magic or not looks a bit suspicious, too. For example, you should start with the assumption that the square is magic and then set your flag to false if one of the conditions for a magic square doesn't hold. You never have to set that flag back to true again. But that's a topic for another question.)
Edit: In order to explain the function better, here's example client code. This is essentially your program without the magic check. N must be a defined constant, as it is in your program.
int main()
{
int array[N][N];
int row, col;
for(row =0; row < N; row++) {
for(col =0; col < N; col++) {
scanf("%d", &array[row][col]);
}
}
if (unique(array)) {
puts("Values are unique");
} else {
puts("There are duplicate values.");
}
return 0;
}

Resources