I wrote this program first, it recursively calculates pi and stops when the error value is small enough.
#include <stdio.h>`
#include <stdlib.h>
#include <math.h>
int threads=1;
double error=0.000001;
double func(double);
struct args{
double l;
double r;
double fl;
double fr;
double area;};
double quad(struct args*);
int main(int argc, char *argv[]) {
struct args* res = (struct args*)malloc(sizeof(struct args));
res->l=0;
res->r=1;
res->fl=1;
res->fr=0;
res->area=0;
double ans=quad(res);
free(res);
ans=ans*4;
printf("pi=%f\n",ans);
}
double func(double x){
x=(1-(x*x));
x=sqrt(x);
return x;
}
double quad(struct args* arg){
double m=(arg->l+arg->r)/2;
double fm=func(m);
double larea=(arg->fl+fm)*(m-arg->l)/2;
double rarea = (fm+arg->fr)*(arg->r-m)/2;
struct args* arg1 = (struct args*)malloc(sizeof(struct args));
arg1->l=arg->l;
arg1->r=m;
arg1->fl=arg->fl;
arg1->fr=fm;
arg1->area=larea;
struct args* arg2 = (struct args*)malloc(sizeof(struct args));
arg2->l=m;
arg2->r=arg->r;
arg2->fl=fm;
arg2->fr=arg->fl;
arg2->area=rarea;
if(fabs((larea+rarea)-arg->area)>error){
if(threads<=1){
larea=quad(arg1);
rarea=quad(arg2);
free(arg1);
free(arg2);
}
}
return(larea+rarea);
}
This one works as it should but then I tried to make the quadfunction return a void pointer instead of a double it looked like this.
#include <stdio.h>`
#include <stdlib.h>
#include <math.h>
int threads=1;
double error=0.000001;
double func(double);
struct args{
double l;
double r;
double fl;
double fr;
double area;};
void* quad(struct args*);
int main(int argc, char *argv[]) {
struct args* res = (struct args*)malloc(sizeof(struct args));
res->l=0;
res->r=1;
res->fl=1;
res->fr=0;
res->area=0;
void* ans=quad(res);
double val=*(double*)ans;
val=val*4;
free(res);
printf("pi=%f\n",val);
}
double func(double x){
x=(1-(x*x));
x=sqrt(x);
return x;
}
void* quad(struct args* arg){
double m=(arg->l+arg->r)/2;
double fm=func(m);
double larea=(arg->fl+fm)*(m-arg->l)/2;
double rarea = (fm+arg->fr)*(arg->r-m)/2;
struct args* arg1 = (struct args*)malloc(sizeof(struct args));
arg1->l=arg->l;
arg1->r=m;
arg1->fl=arg->fl;
arg1->fr=fm;
arg1->area=larea;
struct args* arg2 = (struct args*)malloc(sizeof(struct args));
arg2->l=m;
arg2->r=arg->r;
arg2->fl=fm;
arg2->fr=arg->fl;
arg2->area=rarea;
if(fabs((larea+rarea)-arg->area)>error){
if(threads<=1){
void* p1=quad(arg1);
void* p2=quad(arg2);
larea=*((double*)p1);
rarea=*((double*)p2);
free(arg1);
free(arg2);
}
}
double ret= (larea+rarea);
void*poin=&ret;
return poin;
}
This program while it compiles just gives me a completely different result, 0.042298 rather than 3.14159. I'm pretty new to C and using pointer so I'm sure I messed something up with the conversions but I can't for the life of me figure out where.
Any help figuring out why these two programs produce different results would be appreciated. Thanks.
You are returning a pointer to ret. A variable that is local to quad(). By the time you look at it it has been replaced.
Also dereferencing an invalid pointer is undefined behaviour. Which means your compiler is free to do whatever, like format your hard drive or start WW3.
Your non-working function returns a pointer to a local variable which will go out of scope and life when the function ends.
double ret = (larea+rarea);
void *poin = &ret;
return poin;
Whereas the working version returns the actual double value.
Why ever did you change the function to return a void* pointer anyway?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With