调用 gsl_integration 时出现分段错误
Segmentation fault while calling gsl_integration
我正在尝试从 Numerical Recipes 中实现多维积分例程(代码取自 here, pg. 164). The use of wrappers to pass the integrand to void* params
is from here(那里有进一步的参考)。我的 class
声明在 NRquad3d_Const_qags_2.C
中,如下所示
#include <gsl/gsl_integration.h>
gsl_integration_workspace * w1 = gsl_integration_workspace_alloc (100000);
gsl_integration_workspace * w2 = gsl_integration_workspace_alloc (100000);
double func3d(double x, double y, double z);
class NRf3 {
public:
double xsav, ysav;
double ret_int(double z)
{
return func3d(xsav, ysav, z);
}
static double ret_int_wrapper(double z, void *params)
{
return static_cast<NRf3*>(params)->ret_int(z);
}
};
//integrates over the z-variable
class NRf2 {
private:
double z1, z2;
gsl_function F2;
public:
NRf3 f3;
double resultf2, errorf2;
NRf2 (double zz1, double zz2): z1(zz1), z2(zz2) {}
double ret_int_2(double y)
{
f3.ysav = y;
F2.function = &(f3.ret_int_wrapper);
F2.params = &f3;
gsl_integration_qags(&F2, z1, z2, 0, 1e-7, 10, w1, &resultf2, &errorf2);
gsl_integration_workspace_free (w1);
return resultf2;
}
static double ret_int_2_wrapper(double y, void *params)
{
return static_cast<NRf2*>(params)->ret_int_2(y);
}
};
//integrates over the y-variable ==> gives function of x
class output {
private:
gsl_function F;
public:
double result, error;
double integrate(double x, double y1, double y2, double z1, double z2){
NRf2 f2(z1, z2);
f2.f3.xsav = x;
F.function = &(f2.ret_int_2_wrapper);
F.params = &f2;
gsl_integration_qags(&F, y1, y2, 0, 1e-7, 10, w2, &result, &error);
gsl_integration_workspace_free (w2);
return result;
}
};
我这样调用积分器:
#include <stdio.h>
#include </users/.../NRquad3d_Const_qags_2.C>
double func3d(double x, double y, double z)
{
double f = x*y*z;
return f;
}
int main (void)
{
double result;
double error;
double expected = -4.0;
output out ;
result = out.integrate(1.0, -1.0, 1.0, -1.0, 1.0);
printf ("result = % .18f\n", result);
printf ("exact result = % .18f\n", expected);
printf ("actual error = % .18f\n", result - expected);
return 0;
}
代码编译正常,但是 运行 a.out
给我一个段错误。来自 gdb
的回溯给出
#0 0x00007ffff7a4b430 in ?? () from /usr/lib64/libgsl.so.0
#1 0x0000000000400bed in NRf2::ret_int_2 (this=0x7fffffffdbd0, y=-0.97390652851717174) at /users/.../NRquad3d_Const_qags_2.C:45
#2 0x0000000000400c39 in NRf2::ret_int_2_wrapper (y=-0.97390652851717174, params=0x7fffffffdbd0) at /users/.../NRquad3d_Const_qags_2.C:53
#3 0x00007ffff7a49c6e in gsl_integration_qk () from /usr/lib64/libgsl.so.0
#4 0x00007ffff7a4997b in gsl_integration_qk21 () from /usr/lib64/libgsl.so.0
#5 0x00007ffff7a4b4c7 in ?? () from /usr/lib64/libgsl.so.0
#6 0x0000000000400d14 in output::integrate (this=0x7fffffffdc30, x=1, y1=-1, y2=1, z1=-1, z2=1) at /users/.../NRquad3d_Const_qags_2.C:73
#7 0x00000000004009ac in main () at crap_test.cpp:22
(gdb) frame 6
#6 0x0000000000400d14 in output::integrate (this=0x7fffffffdc30, x=1, y1=-1, y2=1, z1=-1, z2=1) at /users/.../NRquad3d_Const_qags_2.C:73
73 gsl_integration_qags(&F, y1, y2, 0, 1e-7, 10, w2, &result, &error);
(gdb) frame 1
#1 0x0000000000400bed in NRf2::ret_int_2 (this=0x7fffffffdbd0, y=-0.97390652851717174) at /users/.../NRquad3d_Const_qags_2.C:45
45 gsl_integration_qags(&F2, z1, z2, 0, 1e-7, 10, w1, &resultf2, &errorf2);
运行 gdb
已经帮助我消除了 w1
和 w2
地址中的冲突,但段错误仍然存在。由于错误似乎发生在 NRf2
中对 qags
的第二次调用中,我认为必须有一个我试图引用的已释放指针,但我似乎找不到它。有人可以帮忙吗?
运行 valgrind
给出以下形式的错误:
==26286== Invalid read of size 8
==26286== at 0x4ED0239: gsl_integration_workspace_free (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x400A54: main (crap_test.cpp:32)
==26286== Address 0x6053090 is 80 bytes inside a block of size 88 free'd
==26286== at 0x4C29D4E: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==26286== by 0x400C39: NRf2::ret_int_2(double) (NRquad3d_Const_qags_2.C:46)
==26286== by 0x400C76: NRf2::ret_int_2_wrapper(double, void*) (NRquad3d_Const_qags_2.C:53)
==26286== by 0x4ECBBA3: gsl_integration_qk (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x4ECB97A: gsl_integration_qk21 (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x4ECD4C6: ??? (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x400D51: output::integrate(double, double, double, double, double) (NRquad3d_Const_qags_2.C:73)
==26286== by 0x4009CB: main (crap_test.cpp:25)
这暗示了我 trying to access freed memory。在我的脚本中,我尝试这样做的唯一地方是行
gsl_integration_workspace_free (w1);
.
.
.
.
gsl_integration_workspace_free (w2);
在 .C
文件中。然后我(重新)将这些行移动到我的 .cpp
文件的末尾并且它有效。
愚蠢的错误,但无论如何我都会回答这个问题,以防有人遇到这个确切的(或类似的!)错误并需要解决方案。
我正在尝试从 Numerical Recipes 中实现多维积分例程(代码取自 here, pg. 164). The use of wrappers to pass the integrand to void* params
is from here(那里有进一步的参考)。我的 class
声明在 NRquad3d_Const_qags_2.C
中,如下所示
#include <gsl/gsl_integration.h>
gsl_integration_workspace * w1 = gsl_integration_workspace_alloc (100000);
gsl_integration_workspace * w2 = gsl_integration_workspace_alloc (100000);
double func3d(double x, double y, double z);
class NRf3 {
public:
double xsav, ysav;
double ret_int(double z)
{
return func3d(xsav, ysav, z);
}
static double ret_int_wrapper(double z, void *params)
{
return static_cast<NRf3*>(params)->ret_int(z);
}
};
//integrates over the z-variable
class NRf2 {
private:
double z1, z2;
gsl_function F2;
public:
NRf3 f3;
double resultf2, errorf2;
NRf2 (double zz1, double zz2): z1(zz1), z2(zz2) {}
double ret_int_2(double y)
{
f3.ysav = y;
F2.function = &(f3.ret_int_wrapper);
F2.params = &f3;
gsl_integration_qags(&F2, z1, z2, 0, 1e-7, 10, w1, &resultf2, &errorf2);
gsl_integration_workspace_free (w1);
return resultf2;
}
static double ret_int_2_wrapper(double y, void *params)
{
return static_cast<NRf2*>(params)->ret_int_2(y);
}
};
//integrates over the y-variable ==> gives function of x
class output {
private:
gsl_function F;
public:
double result, error;
double integrate(double x, double y1, double y2, double z1, double z2){
NRf2 f2(z1, z2);
f2.f3.xsav = x;
F.function = &(f2.ret_int_2_wrapper);
F.params = &f2;
gsl_integration_qags(&F, y1, y2, 0, 1e-7, 10, w2, &result, &error);
gsl_integration_workspace_free (w2);
return result;
}
};
我这样调用积分器:
#include <stdio.h>
#include </users/.../NRquad3d_Const_qags_2.C>
double func3d(double x, double y, double z)
{
double f = x*y*z;
return f;
}
int main (void)
{
double result;
double error;
double expected = -4.0;
output out ;
result = out.integrate(1.0, -1.0, 1.0, -1.0, 1.0);
printf ("result = % .18f\n", result);
printf ("exact result = % .18f\n", expected);
printf ("actual error = % .18f\n", result - expected);
return 0;
}
代码编译正常,但是 运行 a.out
给我一个段错误。来自 gdb
的回溯给出
#0 0x00007ffff7a4b430 in ?? () from /usr/lib64/libgsl.so.0
#1 0x0000000000400bed in NRf2::ret_int_2 (this=0x7fffffffdbd0, y=-0.97390652851717174) at /users/.../NRquad3d_Const_qags_2.C:45
#2 0x0000000000400c39 in NRf2::ret_int_2_wrapper (y=-0.97390652851717174, params=0x7fffffffdbd0) at /users/.../NRquad3d_Const_qags_2.C:53
#3 0x00007ffff7a49c6e in gsl_integration_qk () from /usr/lib64/libgsl.so.0
#4 0x00007ffff7a4997b in gsl_integration_qk21 () from /usr/lib64/libgsl.so.0
#5 0x00007ffff7a4b4c7 in ?? () from /usr/lib64/libgsl.so.0
#6 0x0000000000400d14 in output::integrate (this=0x7fffffffdc30, x=1, y1=-1, y2=1, z1=-1, z2=1) at /users/.../NRquad3d_Const_qags_2.C:73
#7 0x00000000004009ac in main () at crap_test.cpp:22
(gdb) frame 6
#6 0x0000000000400d14 in output::integrate (this=0x7fffffffdc30, x=1, y1=-1, y2=1, z1=-1, z2=1) at /users/.../NRquad3d_Const_qags_2.C:73
73 gsl_integration_qags(&F, y1, y2, 0, 1e-7, 10, w2, &result, &error);
(gdb) frame 1
#1 0x0000000000400bed in NRf2::ret_int_2 (this=0x7fffffffdbd0, y=-0.97390652851717174) at /users/.../NRquad3d_Const_qags_2.C:45
45 gsl_integration_qags(&F2, z1, z2, 0, 1e-7, 10, w1, &resultf2, &errorf2);
运行 gdb
已经帮助我消除了 w1
和 w2
地址中的冲突,但段错误仍然存在。由于错误似乎发生在 NRf2
中对 qags
的第二次调用中,我认为必须有一个我试图引用的已释放指针,但我似乎找不到它。有人可以帮忙吗?
运行 valgrind
给出以下形式的错误:
==26286== Invalid read of size 8
==26286== at 0x4ED0239: gsl_integration_workspace_free (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x400A54: main (crap_test.cpp:32)
==26286== Address 0x6053090 is 80 bytes inside a block of size 88 free'd
==26286== at 0x4C29D4E: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==26286== by 0x400C39: NRf2::ret_int_2(double) (NRquad3d_Const_qags_2.C:46)
==26286== by 0x400C76: NRf2::ret_int_2_wrapper(double, void*) (NRquad3d_Const_qags_2.C:53)
==26286== by 0x4ECBBA3: gsl_integration_qk (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x4ECB97A: gsl_integration_qk21 (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x4ECD4C6: ??? (in /usr/lib64/libgsl.so.0.16.0)
==26286== by 0x400D51: output::integrate(double, double, double, double, double) (NRquad3d_Const_qags_2.C:73)
==26286== by 0x4009CB: main (crap_test.cpp:25)
这暗示了我 trying to access freed memory。在我的脚本中,我尝试这样做的唯一地方是行
gsl_integration_workspace_free (w1);
.
.
.
.
gsl_integration_workspace_free (w2);
在 .C
文件中。然后我(重新)将这些行移动到我的 .cpp
文件的末尾并且它有效。
愚蠢的错误,但无论如何我都会回答这个问题,以防有人遇到这个确切的(或类似的!)错误并需要解决方案。