-1

I'm using the Gnu Scientific Library to implement a module in my program that computes integrals numerically. The functions are based on the example that can be found on the GSL website in Numerical integration examples:

and here's my code (most of it is the same as in the example):

typedef map<float, float> SignalData;

double f (double x, void * params) {
      SignalData * alpha = static_cast<SignalData *>(params);
      double f =  InterpolatorGSL::interpolatedValueForTime(alpha, x);
      return f;
}


float IntegrationComparator::integral(SignalData * signalData){
       gsl_integration_workspace * w = gsl_integration_workspace_alloc (100000);
       double result, error;
       double expected = -4.0;
       SignalData * alpha = signalData;

       gsl_function F;
       F.function = &f;
       F.params = &alpha;

       gsl_integration_qags (&F, -3.36e-08, -2.36e-08 , 0, 1e-7, 100000,
                             w, &result, &error);

       printf ("result          = % .18f\n", result);
       printf ("exact result    = % .18f\n", expected);
       printf ("estimated error = % .18f\n", error);
       printf ("actual error    = % .18f\n", result - expected);
       printf ("intervals =  %d\n", w->size);

       gsl_integration_workspace_free (w);

}

The problem can be tracked to the following line:

SignalData * alpha = static_cast<SignalData *>(params);

The cast apparently does not work correctly: if I try to do anything with the SignalData object (that is to use any method that takes it as a parameter, ie. a method for printing it out) it produces Segmentation Violation error (it actually prints out 4 random numbers before the error). In the code that I pasted above, it's the interpolation method that uses this object and that's where the Segmentation Violations occurs:

InterpolatorGSL::interpolatedValueForTime(alpha, x);

But this is due to the faulty casting as well.

I don't have much experience with C++ and I've never used void pointers before, so excuse me if this is a stupid question, but what is the right way to pass my map<float, float> * as a void * parameter?

gaige
  • 17,263
  • 6
  • 57
  • 68
Natalia Zoń
  • 980
  • 2
  • 12
  • 22

2 Answers2

4

Let's look at Numerical integration example

   double f (double x, void * params) {
   double alpha = *(double *) params;
   double f = log(alpha*x) / sqrt(x);
   return f;
 }
 ...
   double alpha = 1.0;

   gsl_function F;
   F.function = &f;
   F.params = &alpha;

passed variable has type double * and casted to double * in f function

in your code

double f (double x, void * params) {
  SignalData * alpha = static_cast<SignalData *>(params);
  double f =  InterpolatorGSL::interpolatedValueForTime(alpha, x);
  return f;
}
...
   SignalData * alpha = signalData;

   gsl_function F;
   F.function = &f;
   F.params = &alpha;

you assign SignalData ** but casting it to SignalData *

Thus I would suggest remove one & symbol from your code as following

F.params = alpha;
Nikolay Viskov
  • 1,016
  • 6
  • 9
0

alpha is a local variable in the integral() method, and F.params gets the address of that local variable. I can't quite follow the logic here, but do be aware that when integral() returns, F.params will contain an invalid pointer, and anything -- including a seg fault -- can happen as a result if you try to use it.

Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
  • But I am using the local variable alpha only for gsl_integration_qags() function, which is always called before integral() returns, since it is called inside it and its results are printed out before integral() returns. – Natalia Zoń May 19 '13 at 13:04
  • Besides, even if the `SignalData * alpha pointer` was destroyed, the object that it points to is not, since I'm keeping it in another structure, the database for all signals, and I'm only passing the pointers around. So in the function f we still have a pointer (a copy of the alpha pointer) to a valid object which resides in memory. That's how I think it should work, but again, C++ is not my strongest language, so please correct me if I'm wrong. – Natalia Zoń May 19 '13 at 13:13