У меня есть программа, которая, как предполагается, вычисляет траекторию маятника с методом четвертого порядка рут-кутты и методом эйлера-кромера ... У меня есть segfault.Сегментация Неисправность из-за векторов
Я понятия не имею, как это исправить, так как вы можете видеть, что у меня есть несколько std :: cout для попытки отладки, но они даже не выводятся. Это заставляет меня полагать, что функция никогда не делает это для выполнения main();
Моя текущая интуиция говорит, что она ошибочна во время деклараций функции, но если я ошибаюсь, я хотел бы знать. Если это вообще возможно, можете ли вы описать методы, которые вы использовали для отладки?
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <stdlib.h>
#include <fstream>
#define N 1
// Pendulum Variables
double d_pendLength = 1.0, d_pendMass = 1.0; // Pendulum Properties
double d_viscParam = 1.0, d_gravity = 1.0; //9.80665; // Enviromental Factors
double d_dAmp = 0.0, d_dFreq = 0.0; // Driving Force
double d_initTheta = 0.0, d_initAVel = 0.0; //Initial Conditions
void v_rungekutta(double d_time, std::vector<double> d_pendulum, double d_step);
void v_eulercromer(double d_time, std::vector<double> d_pendulum, double d_step);
double d_derivative(double d_time, std::vector<double> d_pendulum, int i_de);
int main(void)
{
// Numerical Variables
double d_step = 0.01, d_mTime = -1, d_mPeriod = 300;
// Global Variables
double d_time = 0.0, d_period = 0.0, d_limit;
// Function Vectors
std::vector<double> d_pendulum (2);
// Settings
std::string plot = "theta", algo = "rk4";
std::cout << "START!";
std::ofstream file_output;
std::cout << "HAIDATA!";
file_output.open("pendulum.data");
std::cout << "HAI!";
d_pendulum.at(0)= d_initTheta; //Initial Theta
d_pendulum.at(1)= d_initAVel; //Initial Omega
std::cout <<"BAI!";
if (d_mPeriod > 0)
{
d_limit = d_mPeriod;
}
else if (d_mTime > 0)
{
d_limit = d_mTime;
}
else
{
std::cout << "No Limit Specified";
exit(1);
}
for (int i_currentStep=1; i_currentStep*d_step<=d_limit;i_currentStep++)
{
d_time = i_currentStep*d_step;
if (algo == "rk4")
{
v_rungekutta(d_time, d_pendulum, d_step);
}
else if (algo == "ec")
{
v_eulercromer(d_time, d_pendulum, d_step);
}
file_output << d_time << d_pendulum.at(0) << d_pendulum.at(1) << std::endl;
}
file_output.close();
d_pendulum.clear();
return 0;
}
void v_rungekutta(double d_time, std::vector<double> d_pendulum, double d_step)
{
double h=d_step/2.0;
std::vector<double> t1, t2, t3, k1, k2, k3, k4;
int i;
for (i=N;i>0;i--) t1[i]=d_pendulum.at(i)+0.5*(k1[i]=d_step*d_derivative(d_time, d_pendulum, i));
for (i=N;i>0;i--) t2[i]=d_pendulum.at(i)+0.5*(k2[i]=d_step*d_derivative(d_time+h, t1, i));
for (i=N;i>0;i--) t3[i]=d_pendulum.at(i)+ (k3[i]=d_step*d_derivative(d_time+h, t2, i));
for (i=N;i>0;i--) k4[i]=d_step*d_derivative(d_time+d_step, t3, i);
for (i=N;i>0;i--) d_pendulum.at(i) += (k1[i]+2*k2[i]+2*k3[i]+k4[i])/6.0;
}
void v_eulercromer(double d_time, std::vector<double> d_pendulum, double d_step)
{
int i;
for (i=N;i>0;i--) d_pendulum.at(i) += d_derivative(d_time, d_pendulum, i)*d_step;
}
double d_derivative(double d_time, std::vector<double> d_pendulum, int i_de)
{
double dtheta = d_pendulum.at(1);
if (i_de==0) return dtheta;
double domega = d_pendulum.at(1)+((-d_gravity/d_pendLength)*sin(d_pendulum.at(0)))+(-d_viscParam*(d_pendulum.at(1)))+(d_dAmp*sin(d_dFreq*d_time));
if (i_de==1) return domega;
if (i_de < 0) return 0; // 0 is a possible value, exit with exit func.
}
РЕШЕНИЕ
Моя проблема заключалась в том, что я не был должным образом доступ векторов в rungekutta и я не дал им стартовый размер.
Перед
void v_rungekutta(double d_time, std::vector<double> d_pendulum, double d_step)
{
double h=d_step/2.0;
std::vector<double> t1, t2, t3, k1, k2, k3, k4;
int i;
for (i=N;i>0;i--) t1[i]=d_pendulum.at(i)+0.5*(k1[i]=d_step*d_derivative(d_time, d_pendulum, i));
for (i=N;i>0;i--) t2[i]=d_pendulum.at(i)+0.5*(k2[i]=d_step*d_derivative(d_time+h, t1, i));
for (i=N;i>0;i--) t3[i]=d_pendulum.at(i)+ (k3[i]=d_step*d_derivative(d_time+h, t2, i));
for (i=N;i>0;i--) k4[i]=d_step*d_derivative(d_time+d_step, t3, i);
for (i=N;i>0;i--) d_pendulum.at(i) += (k1[i]+2*k2[i]+2*k3[i]+k4[i])/6.0;
}
После:
void v_rungekutta(double d_time, std::vector<double> d_pendulum, double d_step)
{
double h=d_step/2.0;
std::vector<double> t1 (2), t2 (2), t3 (2), k1 (2), k2 (2), k3 (2), k4 (2);
int i;
for (i=N;i>0;i--) t1.at(i)=d_pendulum.at(i)+0.5*(k1.at(i)=d_step*d_derivative(d_time, d_pendulum, i));
for (i=N;i>0;i--) t2.at(i)=d_pendulum.at(i)+0.5*(k2.at(i)=d_step*d_derivative(d_time+h, t1, i));
for (i=N;i>0;i--) t3.at(i)=d_pendulum.at(i)+ (k3.at(i)=d_step*d_derivative(d_time+h, t2, i));
for (i=N;i>0;i--) k4.at(i)=d_step*d_derivative(d_time+d_step, t3, i);
for (i=N;i>0;i--) d_pendulum.at(i) += (k1[i]+2*k2[i]+2*k3[i]+k4[i])/6.0;
}
Попробуйте отладчик, такой как gdb, lldb или тот, что в Visual Studio. Время, потраченное на их обучение, хорошо потрачено. –
Кстати, объявления функций не выполняются. Компилятор создаст исполняемый файл, который запускается в начале вашей функции 'main()' (возможно, с некоторой статической инициализацией заранее). – user1118321
Я запускаю дистрибутив Linux, поэтому я использовал gdb. Я узнал, что я не использовал .at (i) на некоторых массивах, и что я не дал ни одного размера. Большое спасибо! – NictraSavios