[英]Cast from void * produces Segmentation Violation error
I'm using the Gnu Scientific Library to implement a module in my program that computes integrals numerically. 我正在使用Gnu科学图书馆在我的程序中实现一个模块,该模块以数字方式计算积分。 The functions are based on the example that can be found on the GSL website in Numerical integration examples : 这些函数基于可以在GSL网站上的数值积分示例中找到的示例 :
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 = α
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). 强制转换显然无法正常工作:如果我尝试对SignalData对象执行任何操作(即使用将其作为参数的任何方法,即打印出来的方法),则会产生细分违规错误(实际上会打印出错误前的4个随机数)。 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? 我没有使用C ++的丰富经验,并且以前从未使用过void指针,所以请问这是一个愚蠢的问题,但是将map<float, float> *
作为void *
参数传递的正确方法是什么? ?
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 = α
passed variable has type double *
and casted to double *
in f
function 传递的变量的类型为double *
并在f
函数中强制转换为double *
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 = α
you assign SignalData **
but casting it to SignalData *
您分配SignalData **
但将其强制转换为SignalData *
Thus I would suggest remove one &
symbol from your code as following 因此,我建议从您的代码中删除一个&
符号,如下所示
F.params = alpha;
alpha
is a local variable in the integral()
method, and F.params
gets the address of that local variable. alpha
是F.params
integral()
方法中的局部变量,而F.params
获取该局部变量的地址。 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. 我在这里不太理解逻辑,但是要知道,当F.params
integral()
返回时, F.params
将包含无效的指针,如果尝试使用,可能会发生任何事情(包括seg错误)它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.