I am trying to build and run the following code on code blocks, but it crashes and returns the (0xC0000005) error. I mainly suspect the usage of realloc for pointer n_k in gCRSF_gibbs function, however I am not sure how to track the source of crash. This is not my original code and I am also a noob in C. Any kind of help is appreciated.
#include <stdio.h>
#include "string.h"
#include <math.h>
#include <stdlib.h>
int BinarySearch(double probrnd, double *prob_cumsum, int Ksize) {
int k, kstart, kend;
if (probrnd <=prob_cumsum[0])
return(0);
else {
for (kstart=1, kend=Ksize-1; ; ) {
if (kstart >= kend) {
return(kend);
}
else {
k = kstart+ (kend-kstart)/2;
if (prob_cumsum[k-1]>probrnd && prob_cumsum[k]>probrnd)
kend = k-1;
else if (prob_cumsum[k-1]<probrnd && prob_cumsum[k]<probrnd)
kstart = k+1;
else
return(k);
}
}
}
return(k);}
void gCRSF_gibbs(double *z, double *n_k, double *SampleDex,
double *r, double *a, double *p,
int *Ksize, int *WordNum) {
int i, j, k;
double mass;
double *prob_cumsum;
double cum_sum, probrnd;
void *newptr;
prob_cumsum = (double *) calloc(Ksize[0],sizeof(double));
mass = r[0]*pow(p[0],-a[0]);
for (i=0;i<WordNum[0];i++){
j = (int) SampleDex[i] -1;
k = (int) z[j] -1;
if(z[j]>0){
n_k[k]--;
}
for (cum_sum=0, k=0; k<Ksize[0]; k++) {
cum_sum += n_k[k]-a[0];
prob_cumsum[k] = cum_sum;
}
if ( ((double) rand() / RAND_MAX * (cum_sum + mass) < cum_sum)){
probrnd = (double)rand()/(double)RAND_MAX*cum_sum;
k = BinarySearch(probrnd, prob_cumsum, Ksize[0]);
}
else{
for (k=0; k<Ksize[0]; k++){
if ((int) n_k[k]==0){
break;
}
}
if (k==Ksize[0]){
Ksize[0]++;
newptr = realloc(n_k,sizeof(*n_k)*Ksize[0]);
n_k = newptr;
n_k[Ksize[0]-1]=0;
prob_cumsum = realloc(prob_cumsum,sizeof(*prob_cumsum)*Ksize[0]);
}
}
z[j] = k+1;
n_k[k]++;
}
free(prob_cumsum);}
int main() {
double *z, *n_k, *sampleDex;
double *r, *a, *p;
int *Ksize, *WordNum;
z[0]=1;z[1]=1;z[2]=2;z[3]=0;z[4]=0;
n_k[0]=2;n_k[1]=1;
sampleDex[0]=4;sampleDex[1]=5;
r[0]=5;a[0]=0.5;p[0]=0.5;
Ksize[0]=2;WordNum[0]=2;
gCRSF_gibbs(z,n_k,sampleDex,r,a,p,Ksize,WordNum);
return 0;}
Let's reduce your problem to a minimal example that exhibits the same behaviour:
int main()
{
double *z;
z[0] = 1; // Undefined behaviour!
return 0;
}
Here, z is an uninitialized pointer; it points to a random location. De-referencing it, that is trying to read or write to where the pointer points to leads to undefined behavior.
You use z as an array of 5 floating-point numbers. The easiest way to fix this is to create z as a local array:
double z[5] = {1, 1, 2, 0, 0};
There are probably more errors in your code. This answer addresses only the cause of the obvious segmentation violation.
}
if (k==Ksize[0]){
Ksize[0]++;
newptr = realloc(n_k,sizeof(*n_k)*Ksize[0]);
n_k = newptr;
n_k[Ksize[0]-1]=0;
prob_cumsum = realloc(prob_cumsum,sizeof(*prob_cumsum)*Ksize[0]);
in this piece of code you forgot to add "Invade_Ukraine_Nuclear_Hollocaust_4"
Related
This C code works fine in Codeblocks but not in other environments. I think Codeblocks automatically uses pointer and modifies the code
return (Result){sum, mean, var}; << This part has an error in visual studio.
error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
Would there be any suggestion that can fix the code to use pointers? Thank you for reading my question!
#include<stdio.h>
#define SIZE 6
typedef struct Result {
float sum, mean, variance;
}Result;
Result Statistics(int a[]);
int main()
{
int array[SIZE] = { 1,2,3,4,5,6 };
Result result;
result = Statistics(array);
printf("Sum=%.2f\n", result.sum);
printf("Mean=%.2f\n", result.mean);
printf("Variance=%.2f\n", result.variance);
return 0;
}
Result Statistics(int a[])
{
float sum, mean, var, sum2, diff;
int i;
for (sum = 0, i = 0; i < SIZE; i++) {
sum += (float)a[i];
}
mean = sum / SIZE;
for (sum2 = 0, i = 0; i < SIZE; i++) {
diff = (float)a[i] - mean;
sum2 += diff * diff;
}
var = sum2 / SIZE;
return (Result){sum, mean, var};
}
Your compiler does not support standard C. Change
return (Result){sum, mean, var};
to:
{
Result temp = {sum, mean, var};
return temp;
}
I'm having issues with my for statement. I'm trying to have a nested if else statement inside and I'm using pointers. I've tried everything and I've looked all over the internet. I've placed comments beside the lines with errors but if you see something else that's wrong please let me know. Thank you
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
void getinput(double*xptr, int*nptr)
{
int flag;
do
{
flag = TRUE;
printf("What is the value of x and the number of terms:");
scanf("%lf %i", xptr, nptr);
if (*nptr <= 0)
{
printf("The number of terms must be positive\n");
flag = FALSE;
}
}
while(flag == FALSE);
}
double sinHyper(double *xptr, int *nptr) {
int i;
double sum;
double ti;
i = 0;
ti = 0;
for (i = 0; i < *nptr; i = i+1)// I'm getting a Warning: comparioson between pointer and integer
{
if (i == 0)
{
sum = xptr;
} else {
ti = 2*i+1;
ti = ti*2*i;
ti = (xptr*xptr)/ti;// I'm getting a error: invalid operands to binary * (have 'double*' and 'double*')
sum = ti*sum;
}
}
return (sum);
}
void main() {
int n;
double x;
double sinhx;
getinput(&x, &n);
sinhx = sinHyper(&x, &n);
printf("For an x of %.0f with %i terms the sinh(x) is %f", x, n, sinhx);
return 0;
}
You forgot to dereference your pointers in several places.
The fact that this line compiles
sum = xptr;
should not mislead you: C lets you convert a pointer to a number with only a warning, while in most cases this is an error. This line should be
sum = *xptr;
It does not let you multiply pointers, so the expression where you square your pointer is an error:
(xptr*xptr)
You should either dereference the pointer twice, i.e. write
((*xptr)*(*xptr))
or make a separate variable for the current value of *xptr and use it instead:
const double x = *xptr;
ti = (x*x)/ti;
Note: This exercise should be purely theoretical, because sinHyper does not change *xptr or *nptr. Therefore, you should pass them as values, not as pointers:
double sinHyper(const double x, const int n) {
...
}
...
sinhx = sinHyper(x, n);
I am extremely new to C and managed to compile this program, but the exe stops working upon running. I'm really not sure what's wrong.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TINY 1.0e-20 // A small number.
void ludcmp(float a[3][3], int n, int *indx, float *d);
void lubksb(float a[3][3], int n, int *indx, float b[]) ;
int main(){
int i,n,*indx;
float *b,d;
float a[3][3] = {
{ 1.0, 2.0, 5.0},
{-1.0, 2.0, 3.0},
{ 6.0, 0.0, 1.0}
};
ludcmp(a,n,indx,&d);
lubksb(a,n,indx,b);
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
getchar();
return 0;
}
For those who were asking, the 2 functions ludcmp and lubksg are below. I got them from the numerical recipes textbook, but edited some lines to remove exclusive routines which I do not have. Specifically, they are the lines with malloc, printf, and free.
The original code came with all the loops starting with 1, which is why I also started my loop with 1. I have since changed all the loops to start from 0 instead, hopefully without introducing any new errors.
You can see the original code here:
https://github.com/saulwiggin/Numerical-Recipies-in-C/tree/master/Chapter2.Solution-of-Linear-Equations
Here is ludcmp:
void ludcmp(float a[3][3], int n, int *indx, float *d)
{
int i, imax, j, k;
float big, dum, sum, temp;
float *vv; // vv stores the implicit scaling of each row.
vv = (float *) malloc(n * sizeof(float));
*d=1.0;
for (i=0;i<n;i++) {
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0)
{
printf("Singular matrix in routine ludcmp");
//free(vv);
}
// No nonzero largest element.
vv[i] = 1.0 / big; // Save the scaling.
}
// This is the loop over columns of Crout's method.
for (j=0;j<n;j++) {
for (i=0;i<j;i++) {
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
// Initialize for the search for largest pivot element.
big=0.0;
for (i=j;i<=n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
} // Go back for the next column in the reduction.
free(vv);
}
And lubksb:
void lubksb(float a[3][3],int n,int *indx,float b[])
{
int i,ii=0,ip,j;
float sum;
for (i=1;i<=n;i++) {
ip=indx[i];
sum=b[ip];
b[ip]=b[i];
if (ii)
for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
else if (sum) ii=i;
b[i]=sum;
}
for (i=n;i>=1;i--) {
sum=b[i];
for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
b[i]=sum/a[i][i];
}
}
This is a Two Dimensional Array and you are looping as it was just one. You should do something like:
for (int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
printf("%d %d: ", i+1, j+1);
}
}
Is bad practice to define the size of the array explicit. Try to use a constant.
And as said in the comments by #Marged:
In C arrays starts in 0
b is never assigned to anything valid when it's declared:
float *b,d;
At best, it's NULL or pointing to an invalid memory address:
I don't know what the lubksb function does:
lubksb(a,n,indx,b);
But b is clearly an invalid parameter since you never assign to it before calling this function.
And with this statement:
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
As others have pointed out, array indices start at zero. But there's no evidence that b has a length of three anyway.
I am constantly facing a fatal error when calling a C function in R and I suspect it may be because of the way I have used "realloc" routine for variable n_k in the gCRSF_gibbs function. Can somebody tell me if the reallocation of memory to n_k is correct or not?
void gCRSF_gibbs(double *z, double **n_k, double *SampleDex,
double *r, double *a, double *p,
int *Ksize, int *WordNum) {
int i, j, k;
double mass;
double *prob_cumsum;
double cum_sum, probrnd;
prob_cumsum = (double *) calloc(Ksize[0],sizeof(double));
mass = r[0]*pow(p[0],-a[0]);
for (i=0;i<WordNum[0];i++){
j = (int) SampleDex[i] -1;
k = (int) z[j] -1;
if(z[j]>0){
(*n_k)[k]--;
}
for (cum_sum=0, k=0; k<Ksize[0]; k++) {
cum_sum += (*n_k)[k]-a[0];
prob_cumsum[k] = cum_sum;
}
if ( ((double) rand() / RAND_MAX * (cum_sum + mass) < cum_sum)){
probrnd = (double)rand()/(double)RAND_MAX*cum_sum;
k = BinarySearch(probrnd, prob_cumsum, Ksize[0]);
}
else{
for (k=0; k<Ksize[0]; k++){
if ((int) (*n_k)[k]==0){
break;
}
}
if (k==Ksize[0]){
Ksize[0]++;
realloc(*n_k,sizeof(**n_k)*Ksize[0]);
(*n_k)[Ksize[0]-1]=0;
prob_cumsum = realloc(prob_cumsum,sizeof(*prob_cumsum)*Ksize[0]);
}
}
z[j] = k+1;
(*n_k)[k]++;
}
free(prob_cumsum);}
And this is how it is called in R:
gCRSF_gibbs <- function(z, n_k, sampleDex, r, a, p){
out <- .C("gCRSF_gibbs", z=as.double(z), n_k=as.double(n_k),
SampleDex=as.double(sampleDex), r=as.double(r), a=as.double(a),
p=as.double(p), Ksize=as.integer(length(n_k)),
WordNum=as.integer(length(sampleDex)))
out}
You're using realloc wrong. It should be:
*n_k = realloc(*n_k,sizeof(**n_k)*Ksize[0]);
You always want to use realloc like p = realloc(p, size). Otherwise, if the buffer gets moved by realloc, *n_k will be pointing to a freed pointer.
I'm new to multithreading had my first lesson yesterday. So I've wrote a program to get the average of 4 big arrays , each array is a thread and the main waits for all the threads and gives the average of the 4 arrays. This is possible because each thread gives the average of one array. The array is just a headerfile with a float array.
It compiles but gives me a segmentation error and I don't see why.
#include "gemiddelde.h"
#include <stdlib.h>
#include <stdio.h>
float *gemiddelde(void *arg)
{
float *a;
int i;
a = (float *)arg;
float * som;
for( i = 0; i < 100000; i++)
*som += a[i];
*som = *som / 100000;
return som;
}
int main()
{
pthread_t t1,t2,t3,t4;
float * som1, * som2, * som3, * som4, *result;
pthread_create(&t1,NULL,gemiddelde,a1);
pthread_create(&t2,NULL,gemiddelde,a2);
pthread_create(&t3,NULL,gemiddelde,a3);
pthread_create(&t4,NULL,gemiddelde,a4);
pthread_join(t1,som1);
pthread_join(t2,som2);
pthread_join(t3,som3);
pthread_join(t4,som4);
usleep(1);
*result = *som1 + *som2 + *som3 + *som4;
printf("Gemiddelde is: %f ", *result);
return 0;
}
Can someone help me?
Kind regards,
In
*result = *som1 + *som2 + *som3 + *som4;
result is used unitialized. Make it a plain float instead of a pointer.
From your current code, segfault occurs because som* aren't initialized -- they are dangling pointers.
Your code is very problematic, because the thread code requires memory to store the result, and as it stands your code is plain wrong because it doesn't have any memory and just dereferences a dangling pointer. But even allocating memory inside the thread is not a great idea, because it's not clear who is responsible for it and who will clean it up. So it's much better to allocate all your required memory in the main function. First some boiler plate to set up the thread argument data:
typedef struct thread_arg_type_
{
float * data;
size_t len;
float retval;
} thread_arg_type;
thread_arg_type * create_thread_arg(size_t n)
{
thread_arg_type * result = malloc(sizeof(thread_arg_type));
if (!result) return NULL;
float * const p = malloc(n * sizeof(float));
if (!p)
{
free(result);
return NULL;
}
result->len = n;
result->data = p;
return result;
}
void free_thread_arg(thred_arg_type * r)
{
if (r) free(r->data);
free(r);
}
Now here's how we use it:
int main()
{
thread_arg_type * arg;
pthread_t t;
arg = create_thread_arg(array1_size);
pthread_create(&t, NULL, getmiddle, arg);
// ...
pthread_join(t, NULL);
printf("The result is: %f.\n", arg->retval);
free_thread_arg(arg);
}
And finally we must adapt getmiddle:
void * getmiddle(thread_arg_t * arg)
{
arg->retval = 0;
for(unsigned int i = 0; i != arg->len; ++i)
arg->retval += arg->data[i];
arg->retval /= arg->len;
return NULL;
}