Coding a basic multi-threaded program - c

I want to create 2 threads, one does the max and one gives the average of a list of numbers entered in the command line.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <limits.h>
void * thread1(int length, int array[] )
{
int ii = 0;
int smallest_value = INT_MAX;
for (; ii < length; ++ii)
{
if (array[ii] < smallest_value)
{
smallest_value = array[ii];
}
}
printf("smallest is: %d\n", smallest_value);
}
void * thread2()
{
printf("\n");
}
int main()
{
int average;
int min;
int max;
int how_many;
int i;
int status;
pthread_t tid1,tid2;
printf("How many numbers?: ");
scanf("%d",&how_many);
int ar[how_many];
printf("Enter the list of numbers: ");
for (i=0;i<how_many;i++){
scanf("%d",&ar[i]);
}
//for(i=0;i<how_many;i++)
//printf("%d\n",ar[i]);
pthread_create(&tid1,NULL,thread1(how_many,ar),NULL);
pthread_create(&tid2,NULL,thread2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
exit(0);
}
I just made the first thread, which is to print out the min. number, but I have the following errors when compiling:
How many numbers?: 3
Enter the list of numbers: 1
2
3
Smallest: 1
Segmentation fault
How should I go on and fix the seg. fault?

You can't pass arguments like you're trying to in pthread_create.
Create a structure like:
struct args_t
{
int length;
int * array;
};
then initialize a structure with your array and length.
args_t *a = (args_t*)malloc(sizeof(args_t));
//initialize the array directly from your inputs
Then do
pthread_create(&tid1,NULL,thread1,(void*)a);
Then just cast the argument back to an args_t.
Hope that helps.

Related

Segmentation Fault while printing

#include <stdlib.h>
#include <stdio.h>
#include "string.h"
//This function tries to calculate result of the floor function for floats <= 9999.
int main(int argc, char* argv[]) {
int i, j;
float k;
int x[10000];
for(i = 0; i < 10000; ++i){
x[i] = i;
}
printf("Enter a float in 0..9999: ");
scanf("%f", &k);
tester(x, k);
}
int tester(int* c, int k) {
printf("x[%d] = %d\n", k, c[k]);
}
When I run the program it gives me segmentation fault in here:
printf("x[%d] = %d\n", k, c[k]);
Can anyone see the what problem really is?
You can see the screenshots:
segmentation fault in printf
There are two major problems in your code.
You get input from the user (scanf) as float, but actually use it as int to pass it into the function and as index for the array x.
You should ALWAYS check user input from the terminal (or wherever). In this case the check should be at least, if the actual input is between 0 and 9999.
Improved version:
#include <stdlib.h>
#include <stdio.h>
#include "string.h"
void tester(int* c, int k) {
printf("x[%d] = %d\n", k, c[k]);
}
//This function tries to calculate result of the floor function for floats <= 9999.
int main(int argc, char* argv[]) {
int i;
int k;
int x[10000];
for(i = 0; i < 10000; ++i){
x[i] = i;
}
printf("Enter a float in 0..9999: ");
scanf("%d", &k);
if (k >= 0 && k < 10000) {
tester(x, k);
} else
{
printf("Sorry, your input %d was invalid.", k);
}
}
Probably that will fix your Segmentation Fault problem.

I have an exercise of c

My exercise is input list integer numbers from keyboard and the end of program by 0. Then print sum of array. This is my code:
#include <stdio.h>
#include <stdlib.h>
const int MAX_ITEMS = 50;
void inputIntegerNumber(int* a, int* count);
int sumOfInteger(int* n, int* count);
int main(int argc, char** argv) {
int x[MAX_ITEMS], count;
inputIntegerNumber(&x, &count);
printf("Sum of array is %d", sumOfInteger(&x, &count));
return (EXIT_SUCCESS);
}
void inputIntegerNumber(int* a, int* count ){
do{
printf("Please! input numbers: ");
scanf("%d", a);
*count++;
}while((*a != 0) && (*count != MAX_ITEMS));
}
int sumOfInteger(int* n, int* count){
int sum = 0;
for (int i = 0; i < *count; i++)
sum += *n;
return sum;
}
I don't know what's wrong with it? It doesn't give me a result same my thinks...
There are some problems like -
inputIntegerNumber(&x, &count);
printf("Sum of array is %d", sumOfInteger(&x, &count));
in both calls you pass &x but x is an array of int and your function expects int * not int (*)[]. This must have given an error atleast.
For both functions you can just pass the array x directly.
And in your function inputIntegerNumber this -
*count++;
You need to increment value of count, so it should be (*count)++. Dereference first and then increment the value.
You are doing some mistakes in your code like passing pointer to a pointer &x value(since array is basically a pointer to some memory location) and overwriting the same location again and again. In scanf("%d", a); you are overwriting the first location again and again without changing a in you input loop.You need to learn about arrays and their usage. In sumOfInteger function also you're not changing the value of n. I changed you code a bit and i was able to see desired output.
#include <stdio.h>
#include <stdlib.h>
const int MAX_ITEMS = 50;
void inputIntegerNumber(int* a, int* count);
int sumOfInteger(int* n, int* count);
int main(int argc, char** argv) {
int x[MAX_ITEMS], count = 0; // zero elements in array
inputIntegerNumber(x, &count);
printf("Sum of array is %d", sumOfInteger(x, &count));
return (EXIT_SUCCESS);
}
void inputIntegerNumber(int* a, int* count ){
int aIndex = 0;
do{
printf("Please! input numbers: ");
scanf("%d", &a[aIndex]);
aIndex++;
}while((a[aIndex-1] != 0) && (aIndex != MAX_ITEMS));
*count = aIndex;
}
int sumOfInteger(int* n, int* count){
int sum = 0;
for (int i = 0; i < *count; i++)
sum += n[i];
return sum;
}
when i run it i can see :
~/Documents/src : $ ./a.out
Please! input numbers: 1
Please! input numbers: 2
Please! input numbers: 3
Please! input numbers: 0
Sum of array is 6
You're overcomplicating things. Before you sit down to write a program, always write the general steps that must be done
Read the numbers from the command line
Convert them to ints and save them in memory
Calculate the sum
Print it
Here is the revised program
#include <stdio.h>
#include <stdlib.h> /* for strtol */
#define DIE(msg) fprintf(stderr, "%s", msg); exit(EXIT_FAILURE)
int main(int argc, char *argv[])
{
int *nums;
if (argc <= 1)
DIE("Usage: [int-list]\n");
/* skip program name */
--argc;
++argv;
nums = malloc(argc * sizeof(int));
if (!nums)
DIE("Out of mem\n");
for (int i = 0; i < argc; ++i) {
char *end;
double val = strtol(argv[i], &end, 0);
if (end == argv[i]) /* no digits detected */
DIE("Usage: [int-list]\n");
nums[i] = val;
}
printf("%d\n", add(nums, argc));
free(nums);
}
int add(int arr[], size_t n)
{
int sum = 0;
for (int i = 0; i < n; ++i)
sum += arr[i];
return sum;
}
To complete the strtol error handling is an exercise for the OP.

How to have a dynamic number of threads in C

I would like to calculate a mathematic summation in c using threads.
(∑x^i ,From 0 to N) Each threads should calculate each terms of the summation and finally in the main the program should sum all of them and print them.
How should I make the number of threads dynamically?
Here is my code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <math.h>
pthread_t sadaf[10];
int i,a[10];
long int x,N;
int sum=0;
pthread_mutex_t mtx;
void *Myfun(void *tid)
{
int *ThreadID=(int *)tid;
pthread_mutex_lock(&mtx);
printf("The thread with id of %d calculated x^i\n",*ThreadID);
a[*ThreadID]=pow(x,*ThreadID);
sum=sum+a[*ThreadID];
pthread_mutex_unlock(&mtx);
}
int main()
{
int d[10] = {0};
printf("->**************************************************************************<-\n");
printf("This program will calculate the following function:\n-> ∑x^i ,From 0 to N \n");
printf("->**************************************************************************<-\n");
printf("Please enter x:\n");
scanf("%ld",&x);
printf("Please enter N:\n");
scanf("%ld",&N);
for (i=0; i<N; i++)
{
d[i] = i;
pthread_create(&sadaf[i],NULL,Myfun,(void *)&d[i]);
}
for (i=0; i<N; i++)
{
pthread_join(sadaf[i],NULL);
}
printf("The sum is: %d\n",sum);
}
The d array can hold 10 values, so if N is greater than 10, you have an out of bounds problem:
int d[10] = {0};
...
for (i=0; i<N; i++)
{
d[i] = i; // if i > 10 => you access out of bounds => problem
You have the same problem with other arrays too.
You have only 10 pthreads defined at the beginning.
pthread_t sadaf[10];
Creating more than 10 threads will cause the undefined behaviour.

Pointing to arrays using void function

Sorry for that title. I really didn't know how to define this problem.
I was needed to declare integer array of N numbers and to fill it with random nums in void function. Then that array needs to be printed in main. The thing is that i am not allowed to use printf in void function so only way to print in main is to use pointers I guess. My knowledge is limited as I am beginner at pointers. Thx in advance and sorry for bad english.
Here is my code so far. When I compile it marks segmentation error.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form();
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, &a);
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr[100])
{
srand(time(NULL));
for (int i = 0; i < N; i++) {
*ptr[i] = rand() % 46;
}
There are several issues in your code.
1) Your array decalaration form() is obsolete. Use proper prototype.
2) For declaring a VLA, declare it after reading N instead of using a fixed size array.
3) An array gets converted into a pointer to its first element when passed to a function. See: What is array decaying?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int, int*); /* see (1) */
int main(void) /* Standard complaint prototype for main.
If you need to pass arguments you can use argc, and argv */
{
int N;
printf("Input size: \n");
scanf("%d", &N);
int a[N]; /* see (2) */
form(N, a); /* see (3) */
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr) { /* Modified to match the prototype
srand(time(NULL));
for (int i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}
So a couple things:
void form();
As Olaf was alluding to, this declaration is incorrect - you are missing the applicable parameters. Instead, it should be
void form(int N, int ptr[100]);
The main reason your program is crashing is because of the following line:
*ptr[i] = rand() % 46;
You are dereferencing the pointer at i, which is actaully giving you a number - what you want is to assign the value of the pointer at i the new random value:
ptr[i] = rand() % 46;
As related reading, see this question about passing an array in as a function parameter (basically, int ptr[] is the same thing as int * ptr)
Small modifications on your code:
1) Correction and simplification of parameter handling at function call. Just hand over "a", it's an array, so it is an address, you can use int *ptr, or int ptr[], or int ptr[100] in the formal parameter list for it. So you can use simply ptr[i] in your function.
2) Make a prototype for function from old-style declaration providing parameter list.
3) int i; declaration before the for loop - not mandatory, depends on your compiler standard
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int N, int *ptr);
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, a);
printf("Array: \n");
int i;
for (i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr)
{
srand(time(NULL));
int i;
for (i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}

reversing elements of an integer array

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int reverse(int a[20],int n);
int main()
{
int a[20];
int n;
printf("enter the number of elements \n");
scanf("%d",&n);
printf("enter the array elements\n");
for(int i=0;i<n;i++)
{
scanf("%d ",&a[i]);
}
reverse(a,n);
return 0;
}
int reverse(int a[20],int n)
{
for(int i=n-1;i>=0;i--)
{
printf("%d ",a[i]);
}
return 0;
}
here if I input n=4 then during runtime i have to take 5 elements and then it reverses.For eg if i take n=4 and then for no of elements i have to take 1,2,3,4,5 and then only output is coming as 4 3 2 1.Why? is my logic wrong? also in this code I am unable to take the number of elements of arrays in a straight line, like 1 2 3 4.When I am entering the number each number is entering in new line .I am a novice programmer in C and thus having these doubts.Please anyone explain...
The problem with your code is the extra space after %d in your scanf line where you accept array elements i.e.
for(int i=0;i<n;i++)
{
scanf("%d ",&a[i]); //should be scanf("%d",&a[i]);
}
Change that and you're good to go.
Here is your entire program refactored to work correctly:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int reverse(int a[20], int n)
int main()
{
int a[20];
int n;
printf("enter the number of elements \n");
scanf("%d",&n);
printf("enter the array elements\n");
for (int i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
reverse(a,n);
return 0;
}
int reverse(int a[20], int n)
{
int mid = n/2;
for (int i=0; i < mid; ++i)
{
int temp = a[n-i-1];
a[n-i-1] = a[i];
a[i] = temp;
}
return 0;
}

Resources