I have made a program that calculates a ballistic curve according to Runge Kutta 4.
It prints the results in a .csv file to open it in excel afterwards.
The exception is thrown at the point, when i close the file at the end of the method.
It works if i have a small step size, and only write less than 500 entry lines...
I even changed it, so it writes at the end of the calculation.
If I wait between every 100 entrys for a second, it sometimes works.
Btw. I’m very sure it’s not a problem of my calculation, because it works with h=0.1 und duration 3.
void BallisticCalculator::printGraph(float v0, float d, float m, float scopeOffset, float alpha, float h, float duration) {
// constants
static const float Roh = 1.2; // kg/m^3
static const float Cw = 0.3; //a typical Bullet
static const float PI = 3.1415926535;
Vector2D* g = new Vector2D(0, -9.81);
// open file
std::remove("RungeKutta.csv");
std::ofstream myfile;
myfile.open("RungeKutta.csv");
//myfile.open("X:\Math\RungeKutta.csv");
int w = 0; //writing acsess
// converting to SI
float A = (d / 2000) * (d / 2000) * PI; // mm to m^2
m = m / 1000; //gramm to kg
scopeOffset = scopeOffset / 100; //cm to meters
alpha = alpha * PI / (60 * 180); // MOA to degree to radians
// Luftwiderstands Beschleunigung (Luftwiderstandskraft durch masse der Kugel)
double k = Roh * Cw * A / 2 / m;
// data
Bullet* graph = new Bullet[duration / h];
for (double t = 0; t < duration; t += h) {
w++;
int i = (int)(t / h);
if (i == 0) {
graph[i].pos = Vector2D(0, -scopeOffset);
graph[i].v = Vector2D(std::cos(alpha) * v0, std::sin(alpha) * v0);
graph[i].a = acc(graph[i].v, *g, k);
}
else {
Vector2D v1, v2, v3, v4 = Vector2D(0, 0);
v1 = acc(graph[i - 1].v, *g, k);
v2 = acc(graph[i - 1].v + (v1 * (h / 2)), *g, k);
v3 = acc(graph[i - 1].v + (v2 * (h / 2)), *g, k);
v4 = acc(graph[i - 1].v + (v3 * h), *g, k);
graph[i].v = graph[i - 1].v + ((v1 + v2 + v2 + v3 + v3 + v4) * (h / 6));
graph[i].pos = graph[i - 1].pos + (graph[i].v * h);
graph[i].a = acc(graph[i].v, *g, k);
}
Iid like to do it this way:
myfile << t << ";" << graph[i].pos.x << ";" << graph[i].pos.y << ";" << norm(graph[i].v) << ";" << "\n";
// time distance drop speed
//waiting here makes it sometimes possible to work....
if (w > 100) {
myfile.close();
std::cout << "\n" << "Eingabetaste drücken, diese Pause dient zur Entlastung des Schreibsystems...";
std::cin.ignore();
myfile.open("RungeKutta.csv", std::ios::app);
w = 0;
}
}
// for testing purpuses
//for (int i = 0; i < (duration / h); i++) {
// myfile << graph[i].pos.x << ";" << graph[i].pos.y << ";" << norm(graph[i].v) << ";" << "\n";
//}
myfile.close();
//return state;
std::cout << "finished" <<"\n" << "\n";
};
BallisticCalculator::Vector2D BallisticCalculator::acc(Vector2D v, Vector2D g, float k) //v{x,y}, gravity, k = Roh * Cw * A / 2 / m
{
return (v * -k * norm(v))+ g;
}
the Exeption was:
Exception thrown at 0x7A5EB2E7 (ucrtbased.dll) in ConsoleApplicationRungeKutta.exe: 0xC0000005: Access violation writing location 0xC311F2DD.
thrown at the next line after myfile.close();
After discussing this with my co-worker, we found a solution. Although we couldn’t say what’s wrong with it, I’m probably accessing memory I shouldn’t. Defining the Array size of the graph with a rounded Integer didn’t help. And I had to make the Arrays size dynamic.
It works with a vector, so the problem isn’t the fstream …
How to fix it:
//Bullet* graph = new Bullet[duration / h];
std::vector<Bullet> graph; // new
and:
for (double t = 0; t < duration; t += h) {
graph.push_back(Bullet()); //new
It would be intressting, why my array was not working..
User contributions licensed under CC BY-SA 3.0