Calculate the sum of two numbers using thread - c

I have this little program I wrote to read two numbers from a user and calculate their sum using a thread function, which is also responsible for displaying the result on the screen.
int global[2];
void *sum_thread(void *arg)
{
int *args_array;
args_array = *(int**)arg;
int n1,n2,sum;
n1=args_array[0];
n2=args_array[1];
sum = n1+n2;
printf("N1 + N2 = %d\n",sum);
return NULL;
}
int main()
{
printf("First number: ");
scanf("%d",&global[0]);
printf("Second number: ");
scanf("%d",&global[1]);
pthread_t tid_sum;
pthread_create(&tid_sum,NULL,sum_thread,(void*)&global);
pthread_join(tid_sum,NULL);
return 0;
}
However, when I run the code, it does not work properly due to a segmentation fault. I suppose I am trying to access/use unallocated memory. Should I allocate it with malloc or is there other things I am doing wrong?

The name of the array, global points to the base address of the array. You can simply pass that and use the same inside your thread function.
However, just to mention a logical point, if you're passing global as a parameter to sum_thread() function, it need not be a global.
In your code, change
pthread_create(&tid_sum,NULL,sum_thread,(void*)&global);
to
pthread_create(&tid_sum,NULL,sum_thread,global);
Then, in sum_thread() function
args_array = *(int**)arg;
to
args_array = arg;

You pass (void*)&global as the thread start function's argument. The type of &global is (*)int[2] -- pointer to array of two int. That is different from and incompatible with int **, which is a pointer to a pointer to int. Arrays are not pointers.
#SouravGhosh already offered a solution that gets the typing correct, and should work just fine. I observe, however, that in this particular case it's a bit silly to pass a pointer to the global array, because the thread could instead just read the array directly:
void *sum_thread(void *arg)
{
int n1,n2,sum;
n1=global[0];
n2=global[1];
sum = n1+n2;
printf("N1 + N2 = %d\n",sum);
return NULL;
}

Related

Using function to pass the user input via pointers not working

I'm trying to get the input from the user input, and pass to the program main using pointer. It seems that the value isn't going through even tho I tried some alternatives.
For example, if i input 0.0001, when I return to the main function it outputs 0.0000
#include <stdio.h>
void inputFloat(float *n);
int main() {
float *number;
printf("Insert number: ");
inputFloat(number);
printf("%1.4f", *number);
return 0;
}
void inputFloat(float *n){
float num;
while (scanf("%f", &num) != 1 || num < 0) {
scanf("%*[^\n]%*c");
printf("insert positive: ");
}
printf("%1.4f\n", num);
n = &num;
}
Thanks in advance for any tip or correction.
The main problem here is that you forget that in C arguments are passed by value, and that includes pointers.
The argument variable n in the inputFloat function is local to the inputFloat function, all modifications (like assignments) to it will be lost once the function returns.
What I believe you are trying to to is emulating pass by reference, which indeed is done by using pointers. But then you pass a pointer to a normal variable using the address-of operator &:
float number; // Not a pointer
inputFloat(&number); // Pass a pointer to the variable number
To use this pointer, and to set the value of the original variable it points to, you need to dereference the pointer:
void inputFloat(float *n)
{
// ...
*n = num; // Copy the value of num to the location where n is pointing
}

How to pass a parameter from a thread to a function in c

I would like to pass a parameter from my main() into my function. Please let me know how should I do that. I saw some methods in Internet but they didn't work.
Here is the code:
void *deliver(int *i)
{
int *ThreadID=(int *)tid;
//Here I would like to do some comparing on arrays using i parameter
//a[i]>b[i] As an example
}
void main ()
{
pthread_t t2_deliver[100];
//input var
printf("By using this code you can apply T threads on ordering list ;) \n");
printf("->*******************************************************************************<-\n");
printf("Please enter the number of threads(T):\n");
scanf("%d",&threadnum);
for (i=0; i<threadnum; i++)
{
pthread_create(&t2_deliver[i],NULL,deliver,&i);
}
You have a logical error in your code. All threads you create will have a pointer to the same i, meaning it will have the same value in all threads, and will most likely be out of bounds as the threads will run after the loop creating the threads.
One possible solution is to use casting and the standard intptr_t to pass the value to the thread functions:
pthread_create(..., (void*) (intptr_t) i);
And in the thread:
void *deliver(int *p)
{
int i = (int) (intptr_t) p;
...
}
First error that I see is you try to cast not what is in i (argument of function) but in some variable tid.
In principle thread function (in your case deliver) accepts as an argument void pointer, which later can be casted to what you sent, so just to play by the rules I would recommend you that you change function definition so it accepts void pointer as argument, not int pointer. It should not make any difference but is more correct. Why is this better: void pointer is a pointer to some data we don't know yet what it is so we need to cast it in function, this gives us the freedom that we could pass to function whatever we want from simple integers to complex structures. If you then want to get the value that is stored on location passed as function argument you dereference it with * operator. So I'm suggesting you make this modifications, thread function should look something like this:
void *deliver(void *i){
// in p there is integer pointer to argument i
int *p = (int *)i;
// now in ThreadID we have value of argument we passed to function in main (value at address i)
int ThreadID = *p;
//Here I would like to do some comparing on arrays using i parameter
//a[i]>b[i] As an example
}
and when creating threads just to do it right I would do this:
pthread_create(&t2_deliver[i],NULL,deliver,(void *)&i);
Maybe some of the things like type of pointer are not necessary but I think it is more correct and by my experience this works fine and you get the freedom to pass to function everything you want if you then cast it and dereference it correctly. Hope this helps.
Update and fix:
As mentioned in a comment below by Jonathan Leffler passing address of i in for loop (main function) is wrong, because then all threads point with their arguments to the same integer i in memory and effectively to the same value. There are plenty of workarounds, two are mentioned below by Jonathan Leffler, my favourite is constructing array of ids and then assagning and sending each id in array to each of threads:
ind tid[100];
for (int i = 0; i < 100; i++){
tid[i] = i;
pthread_create(&t2_deliver[i],NULL,deliver,(void *)&tid[i]);
}
Sorry for my mistake.

C Passing double pointer from function

I am working on a non homework question that I just can't solve no matter what I try.
The problem is one from Project Euler that involves solving for even Fibonacci numbers and summing them together, I chose this one as a chance to learn more about functions, pointers, and working with large numbers that would be best served by not copying their value but instead passing a memory address.
I currently have the following:
/*Second attempt at fibo 4mil
problem.*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
//MAX is 20 for testing reasons
//Actual value is MAX 0X3D0900
#define MAX 20
//Function will accept even fibo numbers
//then sum them together for output later
void evenCount (double* evenPoint);
int main(void){
double firstVar = 0;
double secondVar = 1;
double thirdVar;
double modVar = 2;
double sumVar;
double count;
for(count = 0; count < MAX; count++){
thirdVar = firstVar + secondVar;
secondVar = firstVar;
firstVar = thirdVar;
if(fmod(firstVar, modVar) == 0){
evenCount(&firstVar);
}
printf("Currently: %.2f\n", firstVar);
}
sumVar = &evenCount();
printf("Final even sum is: %f\n", sumVar);
return 0;
}
void evenCount (double* evenPoint){
double tempOne, tempTwo, tempThree;
tempOne = *evenPoint;
tempThree = tempOne + tempTwo;
tempTwo = tempOne;
tempOne = tempThree;
evenPoint = &tempOne;
}
I can't tell if the data from main() is being properly passed to the evenCount function for them to be summed and have it's value updated to be printed at the end of main().
My questions are:
Do I need a second double pointer in evenCount to pass the final value or can I just reference one value updating it as it loops through?
Does main() need a pointer so that pointer can reference evenCount pointer?
I would really appreciate any help because I have bought a Safari online subscription, have the "C A Reference Manual" sitting next to me but I just can't figure this out. Plus i read over this question and it kind of answered my question, but the person is using multiple function prototypes.
too few arguments to function and can't be used as a function---- beginning C
Thanks to anybody that looks
I am not completely clear about what the evenCount() function is supposed to do.
Fact is that you are calling it the wrong way - sumVar = &evenCount(); is even twice wrong, as it is missing an argument and the & doesn't make sense - and that it doesn't do what you probably want.
Let's have a look:
void evenCount (double* evenPoint){
double tempOne, tempTwo, tempThree;
Here you define three auto variables, but they haven't got a value yet.
tempOne = *evenPoint;
tempThree = tempOne + tempTwo;
What do you expect to be tempTwo here?
tempTwo = tempOne;
tempOne = tempThree;
evenPoint = &tempOne;
You might mean *evenPoint = tempOne here, but I am not sure.
}
I suppose you want a way to make a "step" in terms of Fibonacci numbers. So let's look:
In order to create the "next" Fib number, you need the two previous ones and add them together. So a "step" could be done in a function like
void fibStep(double * curr, double *prev) {
double new = *curr + *prev;
*prev = *curr;
*curr = new;
}
and then
int main(void){
double firstVar = 0;
double secondVar = 1;
double sumVar = 0;
int count; // no need to have this as a double...
for(count = 0; count < MAX; count++){
fibStep(&secondVar, &firstVar);
if(fmod(secondVar, 2) == 0){
sumVar += secondVar);
}
printf("Currently: %.2f\n", secondVar);
}
printf("Final even sum is: %f\n", sumVar);
return 0;
}
I'm not quite sure what evenCount is meant to do as it is. Edit: see below.
From your description of the problem, it seems like you could just do:
int isEven(unsigned int number)
{
return !(number%2);
}
int main()
{
unsigned int first = 1, second = 1, next, sum = 0;
//we already have the first two numbers so start at 2
for(count = 2; count < MAX; count++)
{
next = first+second;
first = second;
second = next;
//we know the starting values are odd (1 & 1) and won't need to be summed so we can test the new value -
if (isEven(second)) //if even (no remainder when dividing by 2)
{ sum+=first;}
}
printf("Final even sum is: %f\n", sum);
}
Note, there is no need for double here (yet). The sum (at n=20) is still far too low to exceed what int can store. (although at this point it is growing quickly)
As for your actual questions:
note: when you don't need a pointer, it is recommended that you don't use one, as all you are going to do is make the code more complex than needed
Do I need a second double pointer in evenCount to pass the final value?
If the function is meant to keep track of the sum, then I'd do it like this:
unsigned int evenSum(unsigned int num = 0)
{
static unsigned int sum = 0; //initialised on first use of function. Value is retained between function calls.
//we test for even here - no longer need to test in calling code
// - making the algorithm simpler
if (isEven(num))
sum += num;
return sum;
}
which can then be called like this:
//adding values:
evenSum( new_value );
//retrieving sum
sum = evenSum();
//or do both:
sum = evenSum( new_value );
If you wanted to store the sum 'locally' though (i.e. as a variable in main, but modify it in the evenSum() function), then yes, you would then need to pass it into the funtion too as a pointer:
void evenSum(unsigned int num, unsigned int * sum)
{
if (isEven(num))
*sum += num;
}
It would be called like this:
sum = 0;
num = 56;
evenSum(num, &sum); //sum is now sum+num
As you pass the address of sum in, when the function de-references it, it modifies the value and not a copy. The number passed in does not need to be passed in as a pointer as it is a (forgetting correct word here, but it means 'basic') type, and passing it by value is actually slightly more efficient as at runtime it can just be loaded into a register, and doesn't rely on memory lookup. Plus, it is easier to read.
Does main() need a pointer so that pointer can reference evenCount pointer?
To be honest, I'm not 100% sure what you are asking here.
If you are asking:
Do I need to store a pointer to the sum in main() to pass into the evenSum() function?
then no.
You can pass a pointer to a 'thing' using the "address of" operator &. I've used it above in the second calling example in the above answer:
unsigned int * sum_pointer = ∑// <--- not needed
evenSum(num, &sum); //sum is now sum+num
^
This passes a pointer to sum
Edit: looking at your code again, is evenCount meant to find the next fibonachi number?
If so, you could do:
void next_fib(unsigned int *previous, unsigned int *current)
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
}
And you would call this like so:
unsigned int val1 = 1, val2 = 1;
next_fib(&val1, &val2); //val2 is now the 3rd fib. #
next_fib(&val1, &val2); //val2 is now the 4th fib. #
To add this to my code from above, the program becomes:
int isEven(double number)
{
return !(number%2);
}
unsigned int evenSum(double num = 0)
{
static double sum = 0;
//we test for even here - no longer need to test in calling code
// - making the algorithm simpler
if (isEven(num))
sum += num;
return sum;
}
void next_fib(unsigned int *previous, unsigned int *current)
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
}
int main()
{
unsigned int first = 1, second = 1;
//we already have the first two numbers so start at 2
for(count = 2; count < MAX; count++)
{
next_fib(&first, &second);
evenSum(second);
}
printf("Final even sum is: %f\n", evenSum());
}
Edit 2:
After reading your edit and some of your comments, and then taking a look at the actual task, you have interpreted the question incorrectly.
The question asks for the sum of all even numbers in the fibbonachi sequence, where the number is less than 4x106. This is thankfully easier and quicker to do than the sum of all the even Fibonacci numbers up to the 4x106th.
Obviously, we need to change the algorithm. Luckily, we split the main bits into functions already, so it's pretty simple, mainly just a change in the loops, though I made a couple more changes too:
bool isEven(unsigned long number)
{
return !(number%2);
}
void next_even_fib(unsigned long *previous, unsigned long *current)
{
do
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
} while (!isEven( *current));
//we could just do 3 passes here without needing the isEven() function
//as the Fibonacci sequence is always O,O,E,O,O,E...
//but this is a more general form
}
int main()
{
//as there is less constraint on knowing which term we are on, we can skip straight to the first even number.
unsigned long first = 1, second = 2;
unsigned long sum = 0;
do
{
//with the sum calculation first, we can break out of the loop before the sum
//we've changed the algorithm so when we get here, second is always even
sum += second;
next_even_fib(&first, &second);
} while (second < 4000000);
printf("Final even sum is: %d\n", sum);
}
Note that I changed the types to unsigned long. This is still an integer value, but one that is guaranteed to be long ( :-P ) enough to store the numbers we need.
Passing of the value is correct but you can't do evenPoint = &tempOne; to return a value from the function. There are two problems in doing that: first is that C supports only pass by value, so when you pass a pointer you are in fact creating a copy of the pointer for the callee. Any modification of the data pointed will be visible to the caller but not modifications to the pointer argument itself. When you modify the pointer argument you are in fact modifying a stack variable that the caller has no access to.
What's the difference between passing by reference vs. passing by value?
You could change your code in the following way:
void evenCount (double** evenPoint){
double tempOne, tempTwo, tempThree;
tempOne = **evenPoint;
tempThree = tempOne + tempTwo;
tempTwo = tempOne;
tempOne = tempThree;
*evenPoint = &tempOne;
}
But that would mean that *evenPoint points to a variable allocated on the stack, precisely on the frame of evenCount. When evenCount returns the frame get popped out of the stack. Accessing that variable after it is outside the stack will cause undefined behavior.
Consider the following example where you call another function A() after evenCount before using evenPoint. A() function frame would be placed in memory at the same location of where evenCount frame was and its local variables might overwrite the value of evenPoint. When you subsequently read evenPoint you will find its value changed.
C++ Returning reference to local variable
Finally, you read the variable tempTwo which is an uninitialized automatic variable so you'll end up reading garbage.

understanding how to dynamically create an array of structure and access its elements

I need to pass the address of a pointer to a structure to a function, which inturn will dynamically allocate the memory for an array of structures and fill in the values.
Now from my calling method, once i return from the func1, i should be able to iterate through the array of structure and display the value of the structure variables.
Can someone explain how to pass the address of the pointer to the structure, also iterating through the array of structures created dynamically ?
my sample code looks like this:
struct test {
int a;
int b;
};
void func1(int *n,struct test **testobj)
{
n=5;
*testobj = (struct test*) malloc(n*sizeof(struct test));
for(i=0;i<n;i++)
{
(*testobj)[i].a=1;
(*testobj)[i].b=2;
}
}
int main()
{
struct test testobj;int n;
func1(&n,&testobj);
for(i=0;i<n;i++)
{
printf("%d %d",(*testobj)[i].a,*testobj)[i].b);
}
free(testobj);
}
In main() define a pointer to a test structure:
struct test *testPtr;
To take the address of that pointer use the & address-of operator:
&testPtr;
This returns the address of the pointer and has type struct test **
You can then pass this into your function func1, which does the correct allocation (although casting malloc() is generally considered bad practice - Do I cast the result of malloc?). Other than that func1() looks good... the line...
*testobj = malloc(n*sizeof(struct test));
... is correct. *testobj dereferences your double pointer that you got by doing &testPtr, and stores the address of the new memory in your pointer. You are also correct when you dereference your double-pointer using (*testobj)[i] because [] has higher precedence than * you needed to (as you've correctly done) surround the dereference with brackets to make sure that happens before you take the index.
Thus, when func1() returns the pointer testPtr should now point to the array of n test structures you allocated and can be accessed using testPtr[i].a etc.
EDIT: Your for loop should become
for(i=0;i<n;i++)
printf("%d %d", testobj[i].a, testobj[i].b);
Your original for loop should have given you compilation errors? In the original code testobj is not a pointer, therefore dereferencing it should not be possible.
So the summary answer is in main() declare testobj as a pointer and then access the array elements as testobj[n] :)
EDIT: As eric has pointed out, remove n=5; from func1(). I think you meant *n=5 perhaps as some kind of debugging step... You probably mean to use n as the input to the function to say how many objects you want in your structure array. Either initialise n or perhaps re-define func1() to be
void func1(int n,struct test **testobj) // n is no longer a poitner, just a number
create your array of pointers to structures in declaration step itself and simply pass it to the function
struct test *testobj[10];
func1(&n,testobj);
This passes the whole array of pointers to the function
It isn't entirely clear which version you're asking for, but one of these should cover it:
/* allocate some number of tests.
*
* out_n: out parameter with array count
* returns: an array of tests
*/
struct test* allocate_some_tests(int *out_n) {
int n = 5; /* hardcoded, random or otherwise unknown to caller */
*out_n = n
struct test *t = malloc(n * sizeof(*t));
while (n--) {
t[n].a = 1;
t[n].b = 2;
}
return t;
}
/* allocate a specific number of tests.
*
* n: in parameter with desired array count
* returns: an array of tests
*/
struct test* allocate_n_tests(int n) {
struct test *t = malloc(n * sizeof(*t));
while (n--) {
t[n].a = 1;
t[n].b = 2;
}
return t;
}
Note that you can just return the allocated array, you don't need a pointer-to-pointer here.
As for calling them, and iterating over the result:
void print_tests(struct test *t, int n) {
for (; n--; t++)
printf("{%d, %d}\n", t->a, t->b);
}
int main()
{
int count1; /* I don't know how many yet */
struct test *array1 = allocate_some_tests(&count1);
print_tests(array1, count1);
int count2 = 3; /* I choose the number */
struct test *array2 = allocate_n_tests(count2);
print_tests(array2, count2);
}
Your code appears pretty much ok to me.
only edit that should make it fine is--
in place of
struct test testobj;
put the following code
struct test *testobj;
and keep the remaining as it is..!
here's the working version of what's required, here the memory is allocated in the called function just as required
#include <stdlib.h>
#include <stdio.h>
struct tests {
int a;
int b;
};
void func1(int *n,struct tests **testobj)
{
int i;
*n=5;
*testobj = (struct tests*) malloc((*n)*sizeof(struct tests));
for(i=0;i<(*n);i++)
{
(*testobj)[i].a=1;
(*testobj)[i].b=2;
}
}
int main()
{
int i;
struct tests *testobj;int n;
func1(&n,&testobj);
for(i=0;i<(n);i++)
{
printf("%d %d",(testobj)[i].a,testobj[i].b);
}
free(testobj);
}

simple pointers to pointers

I know why this works:
#include <stdio.h>
void cool_number(int **number) {
int value = 42;
int *p = &value;
*number = p;
}
int main () {
int *number;
cool_number(&number);
printf("number is %d\n", *number);
return 0;
}
What I don't understand is why this doesn't (in my machine it prints 3700 or something like that).
#include <stdio.h>
void cool_number(int **number) {
int value = 42;
int *p = &value;
int **x = &p;
number = x;
}
int main () {
int *number;
cool_number(&number);
printf("number is %d\n", *number);
return 0;
}
Why aren't both equivalent?
both are evil as they capture the address of a stack variable.
Second one doesn't do what you expect because you are assigning directly to the parameter number, which is only temporary, the first one changes something the parameter number pointers to, which is the same thing as number in main points to.
I assume they're not equivalent because number is passed by value, on the stack, as is standard for function parameters. Any changes that you make directly to number inside of cool_number() are modifying the local copy on the stack, and are not reflected in the value of number in main().
You get around this in the first example by dereferencing number, which tells the computer to modify some specific location in memory that you also happen to have a pointer to back in main(). You don't have this in the second example, so all that happens is that you make the local number pointer point to somewhere else, without actually updating any memory location being referred to back in main(). Thus nothing you do shows up once you get back to main().
And since value is local to the cool_number() function, setting a reference to it that will be accessed after cool_number() returns isn't guaranteed to work and certainly shouldn't be used in any code outside of a trivial/toy example. But in this specific instance it's not really related to why you're seeing different results between the two pieces of code.
As I understand, in both cases, your code is wrong.
In the first case, you are returning an address to a variable allocated on stack, which will be deallocated as soon as the function returns.
In the second case, the error of the first case exists, plus you are passing number by value, so an updation to number will not get reflected in the caller function.
In 'C', arguments are always passed by value. So, you cannot update the argument passed as it is. For Ex:
int func(int a)
{
a = 5; // In this case the value 5 will not be reflected in the caller as what is updated is the local copy of a on the stack
}
int func(int *a)
{
*a = 5; // This update will show in caller as you are directly updating the memory pointed to by a
a = malloc(4); //This update will not show in caller as again you are updating the local copy of stack
}
#include <stdio.h>
void cool_number(int **number) {
int value = 42; /* this "value" hold 42 value,
and it lifetime is only in this function */
int *p = &value; /* here we get the address of "value" in memory */
*number = p;
}
int main () {
int *number;
cool_number(&number); /* after this function the "value" in memory had been recyled
and may be used by other program */
printf("number is %d\n", *number); /* so when we print value here it will be
a unpredictable value, somehow may be crash */
return 0;
}
both the same principle

Resources