如何从 C++ 中的函数内部更改数组
How can I alter an array from inside a function in C++
我正在尝试编写一个 c++ rk4 算法,但无论我尝试什么,我似乎 运行 都会遇到同样的错误。我可以编译程序,但我一直得到 zsh: segmentation fault (core dumped) ./main
。我认为问题出在 rk4 函数中:
void funcs::rk4(double *p_vec, double h)
{
double *k0, *k1, *k2, *k3, *l0, *l1, *l2;
k0 = force( p_vec );
for ( int inst = 0; inst < 2; ++inst )
{
l0[ inst ] = p_vec[ inst ] + h*( k0[ inst ] );
}
k1 = force( l0 );
for ( int inst = 0; inst < 2; ++inst )
{
l1[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k1[ inst ] );
}
k2 = force( l1 );
for ( int inst = 0; inst < 2; ++inst )
{
l2[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k2[ inst ] );
}
k3 = force( l2 );
for ( int inst = 0; inst < 2; ++inst )
{
( p_vec )[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );
}
}
下面是主要功能,如果有帮助的话:
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "functions.h"
using namespace std;
int main( int argc, char **argv )
{
float alpha = 0, beta = 1;
int Number = 1000;
double h = ( beta - alpha )/ Number;
double postiton_0 = 1.0, velocity_0 = 0.0;
vector<double> time = funcs::linspace( alpha, beta, Number );
double p_vector[2] = { postiton_0, velocity_0 };
for ( int inst = 0; inst <= Number; ++inst )
{
funcs::rk4( p_vector, h );
cout << inst << ", " << p_vector[ 0 ]
<< ", " << p_vector[ 1 ] << endl;
}
return 0;
}
非常感谢您!
编辑:
感谢您的快速回复!
这里是源码来源:
double * funcs::force(double *p_vec)
{
double force_position = p_vec[ 0 ], force_velocity = p_vec[ 1 ];
static double force_p_vec[ 2 ];
double force_acceleration = -force_position*force_position;
force_p_vec[ 0 ] = force_velocity;
force_p_vec[ 1 ] = force_acceleration;
return force_p_vec;
}
问题是,当我尝试 运行 没有 rk4 的力函数时,我确实得到了数字,也许这就是我使用指针的方式。没有它们我有什么办法吗?谢谢。
更新:
我决定采纳不使用指针和动态内存分配的建议,并使用了这段代码:
void funcs::rk4(double *p_vec, double h)
{
double temp[ 2 ];
double *k0 = force( p_vec );
for ( int inst = 0; inst < 2; ++inst )
{
temp[ inst ] = p_vec[ inst ] + h*( k0[ inst ] );
}
double *k1 = force( temp );
for ( int inst = 0; inst < 2; ++inst )
{
temp[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k1[ inst ] );
}
double *k2 = force( temp );
for ( int inst = 0; inst < 2; ++inst )
{
temp[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k2[ inst ] );
}
double *k3 = force( temp );
for ( int inst = 0; inst < 2; ++inst )
{
p_vec[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );
}
}
我得到了数字,但它们爆炸到无穷大,这不是预期的效果。这是一个简谐振子。位置和速度应在 1 和 0 之间振荡。我使用相同的力函数。
谢谢!
即使使用最新版本的 funcs::rk4()
仍然存在的一个问题是,您所有的指针(k0
... k3
)都指向 [=] 中的同一个静态缓冲区15=]。因此,当你计算
p_vec[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );
所有k0
... k3
实际上都有k3
的内容。
因此,您需要 funcs::force()
return 数组而不是指针。如您所知,您不能 return C-style 数组。但是,您可以 return std::array
。你的函数变成
std::array<double, 2> funcs::force(double *p_vec)
{
double force_position = p_vec[ 0 ], force_velocity = p_vec[ 1 ];
std::array<double, 2> force_p_vec; //non-static!
double force_acceleration = -force_position*force_position;
force_p_vec[ 0 ] = force_velocity;
force_p_vec[ 1 ] = force_acceleration;
return force_p_vec;
}
每个 k0
... k3
inside funcs::rk4()
也应该声明为 std::array<double, 2>
而不是 double
.
我正在尝试编写一个 c++ rk4 算法,但无论我尝试什么,我似乎 运行 都会遇到同样的错误。我可以编译程序,但我一直得到 zsh: segmentation fault (core dumped) ./main
。我认为问题出在 rk4 函数中:
void funcs::rk4(double *p_vec, double h)
{
double *k0, *k1, *k2, *k3, *l0, *l1, *l2;
k0 = force( p_vec );
for ( int inst = 0; inst < 2; ++inst )
{
l0[ inst ] = p_vec[ inst ] + h*( k0[ inst ] );
}
k1 = force( l0 );
for ( int inst = 0; inst < 2; ++inst )
{
l1[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k1[ inst ] );
}
k2 = force( l1 );
for ( int inst = 0; inst < 2; ++inst )
{
l2[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k2[ inst ] );
}
k3 = force( l2 );
for ( int inst = 0; inst < 2; ++inst )
{
( p_vec )[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );
}
}
下面是主要功能,如果有帮助的话:
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "functions.h"
using namespace std;
int main( int argc, char **argv )
{
float alpha = 0, beta = 1;
int Number = 1000;
double h = ( beta - alpha )/ Number;
double postiton_0 = 1.0, velocity_0 = 0.0;
vector<double> time = funcs::linspace( alpha, beta, Number );
double p_vector[2] = { postiton_0, velocity_0 };
for ( int inst = 0; inst <= Number; ++inst )
{
funcs::rk4( p_vector, h );
cout << inst << ", " << p_vector[ 0 ]
<< ", " << p_vector[ 1 ] << endl;
}
return 0;
}
非常感谢您!
编辑:
感谢您的快速回复!
这里是源码来源:
double * funcs::force(double *p_vec)
{
double force_position = p_vec[ 0 ], force_velocity = p_vec[ 1 ];
static double force_p_vec[ 2 ];
double force_acceleration = -force_position*force_position;
force_p_vec[ 0 ] = force_velocity;
force_p_vec[ 1 ] = force_acceleration;
return force_p_vec;
}
问题是,当我尝试 运行 没有 rk4 的力函数时,我确实得到了数字,也许这就是我使用指针的方式。没有它们我有什么办法吗?谢谢。
更新:
我决定采纳不使用指针和动态内存分配的建议,并使用了这段代码:
void funcs::rk4(double *p_vec, double h)
{
double temp[ 2 ];
double *k0 = force( p_vec );
for ( int inst = 0; inst < 2; ++inst )
{
temp[ inst ] = p_vec[ inst ] + h*( k0[ inst ] );
}
double *k1 = force( temp );
for ( int inst = 0; inst < 2; ++inst )
{
temp[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k1[ inst ] );
}
double *k2 = force( temp );
for ( int inst = 0; inst < 2; ++inst )
{
temp[ inst ] = p_vec[ inst ] + ( h/2 ) * ( k2[ inst ] );
}
double *k3 = force( temp );
for ( int inst = 0; inst < 2; ++inst )
{
p_vec[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );
}
}
我得到了数字,但它们爆炸到无穷大,这不是预期的效果。这是一个简谐振子。位置和速度应在 1 和 0 之间振荡。我使用相同的力函数。
谢谢!
即使使用最新版本的 funcs::rk4()
仍然存在的一个问题是,您所有的指针(k0
... k3
)都指向 [=] 中的同一个静态缓冲区15=]。因此,当你计算
p_vec[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );
所有k0
... k3
实际上都有k3
的内容。
因此,您需要 funcs::force()
return 数组而不是指针。如您所知,您不能 return C-style 数组。但是,您可以 return std::array
。你的函数变成
std::array<double, 2> funcs::force(double *p_vec)
{
double force_position = p_vec[ 0 ], force_velocity = p_vec[ 1 ];
std::array<double, 2> force_p_vec; //non-static!
double force_acceleration = -force_position*force_position;
force_p_vec[ 0 ] = force_velocity;
force_p_vec[ 1 ] = force_acceleration;
return force_p_vec;
}
每个 k0
... k3
inside funcs::rk4()
也应该声明为 std::array<double, 2>
而不是 double
.