【问题标题】:How can I alter an array from inside a function in C++如何从 C++ 中的函数内部更改数组
【发布时间】:2021-01-14 10:18:07
【问题描述】:

我正在尝试编写一个 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 的情况下运行 force 函数时,我确实得到了数字,也许这是我使用指针的方式。没有它们我有什么办法吗?谢谢。

更新:

我决定接受不使用指针和动态内存分配的建议,并使用了以下代码:

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 之间振荡。我使用的是相同的力函数。

谢谢!

【问题讨论】:

  • 你能告诉我们force的来源吗?我怀疑它与double *force(double v[3]){double r[3]; …; return r;} 类似,它会引发未定义的行为。
  • 请提供minimal reproducible example 来证明您的问题。
  • 你有很多指针(例如l0),但你从来没有让它们指向任何地方。也许您可能需要更多地研究指针、数组及其关系。并学习如何使用 C++ 标准库提供的工具,如std::vector
  • 是的,l0[ inst ] = ... 未定义的行为 - 事情是,您甚至不需要一个指针或任何手动内存管理来执行此操作。它只会让事情变得更加复杂。

标签: c++ arrays c++11 physics numerical-integration


【解决方案1】:

即使使用最新版本的funcs::rk4(),仍然存在的一个问题是所有指针(k0 ...k3)都指向funcs::force() 内的同一个静态缓冲区。因此,当你在计算时

p_vec[ inst ] += ( ( k0[ inst ] ) + 2*( k1[ inst ] ) + 2* ( k2[ inst ] ) + ( k3[ inst ] ) )*( h/6 );

所有k0 ... k3 实际上都有k3 的内容。

所以,你需要funcs::force() 返回一个数组而不是一个指针。如您所知,您不能返回 C 样式的数组。但是,您可以返回 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;
}

funcs::rk4() 内的每个k0 ... k3 也应声明为std::array&lt;double, 2&gt; 而不是double

【讨论】:

    猜你喜欢
    • 2016-04-22
    • 2021-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 2020-09-25
    相关资源
    最近更新 更多