c++ - C++ 打印到文件未按预期工作
问题描述
我昨天尝试发布这个问题,但我做得很差。这次我将提供完整的算法,并希望能找到答案。我真的很想能够理解为什么这段代码会这样。如果重要的话,我在使用 VS Code 的 Windows 10 上。
我为类编写了一个程序,使用显式欧拉方法对钟摆的运动进行数值求解。我想将我的解决方案数据写入一个文本文件,以便在单独的程序中进行绘图。问题是,当我将数据写入文件时,它只打印到第 341 行,而我期望 1001 行。
但是,如果我包括下面显示的使用 cout 将所有数据打印到屏幕的行(在显式欧拉循环中,当前已注释掉),那么数据将完全正确地打印到文件中,正如我所期望的那样。为什么会这样?如果没有那条特定的行,为什么它不能工作?
我确定我在这里遗漏了一些东西,或者我在不知不觉中创建了某种类型的未定义行为。一般来说,如果有人对如何改进我的代码有任何建设性的建议,我很高兴听到它。
#include <iostream>
#include <vector>
#include <cmath>
#include <fstream>
using namespace std;
int main(){
double L = 0.6;
double g = 9.81;
double co = - g / L;
double dt = 1E-02; // time step [s]
double tend = 10; // end time [s]
double deg2rad = M_PI / 180.0; // conversion factor from deg to radian
double tstep = tend / dt; // calculate number of time steps
unsigned int n = static_cast<unsigned int>(tstep) + 1; // number of elements
int Ncase = 5; // number of cases to evaluate initial value of theta
vector<double> th0(Ncase,0.0); // vector to hold initial amplitude values to test
vector<double> tvec(n,0.0); // vector to hold initial amplitude values to test
vector< vector<double> > z1; // sln (theta) data for Method (1), any theta
vector< vector<double> > w1; // sln (derivative of theta) data for Method (1), any theta
// =====================
// Fill in initial guesses of theta, in degrees
th0[0] = 2.0; th0[1] = 5.0; th0[2] = 7.5; th0[3] = 10.0; th0[4] = 15.0;
// Convert to radians
for ( int i(0); i<Ncase; ++i ){
th0[i] *= deg2rad;
}
// Pre-allocate the solution matrices
for ( int i(0); i<Ncase; ++i){
vector<double> tmp(n,0.0);
w1.push_back(tmp);
tmp[0] = th0[i];
z1.push_back(tmp);
}
// Create time vector
for ( int i(0); i<n; ++i ){
tvec[i+1] = tvec[i] + dt;
}
// Explicit Euler Loops
for ( int i(0); i<Ncase; ++i){ // Case loop
for ( int j(0); j<n; ++j){ // Time loop
z1[i][j+1] = z1[i][j] + dt * w1[i][j]; // Solve for z, method (1)
// cout << "Row: " << i << " Col: " << j << " w1[i][j]: " << w1[i][j] << " dt: " << dt << " z1[i][j]: " << z1[i][j] << endl; // This line makes it print to file correctly
w1[i][j+1] = w1[i][j] + dt * ( co * sin(z1[i][j]) ); // Solve for w, method (1)
}
}
// Write data to file, it is row-wise, write it as column-wise (i.e. transpose)
ofstream sln1_data; // declare file handle
sln1_data.open("Sln1.dat"); // open file for w1riting
sln1_data << "t th0 th1 th2 th3 th4" << endl; // Header line
for ( int i(0); i<n; ++i){ // Solution column-wise into file
sln1_data << tvec[i] << " ";
for ( int j(0); j<Ncase; ++j){
sln1_data << z1[j][i] << " ";
}
sln1_data << endl;
}
sln1_data.close();
}
解决方案
将边界检查添加到您的代码中,您会看到您在很多地方访问数组越界。
...
// Create time vector
for ( int i(0); i<n; ++i ){
if(tvec.size() <= (i+1))
std::cerr << "access out of bounds in tvec loop" << std::endl;
tvec[i+1] = tvec[i] + dt;
}
// Explicit Euler Loops
for ( int i(0); i<Ncase; ++i){ // Case loop
for ( int j(0); j<n; ++j){ // Time loop
if (z1.size() <= i)
std::cerr << "access out of bounds z1" << std::endl;
if (z1[i].size() <= (j+1))
std::cerr << "access out of bounds z1[i]" << std::endl;
if (w1.size() <= i)
std::cerr << "access out of bounds w1" << std::endl;
if (w1[i].size() <= (j+1))
std::cerr << "access out of bounds w1[i]" << std::endl;
z1[i][j+1] = z1[i][j] + dt * w1[i][j]; // Solve for z, method (1)
// cout << "Row: " << i << " Col: " << j << " w1[i][j]: " << w1[i][j] << " dt: " << dt << " z1[i][j]
w1[i][j+1] = w1[i][j] + dt * ( co * sin(z1[i][j]) ); // Solve for w, method (1)
}
}
...
输出:
在 tvec 循环中
访问越界 访问越界 z1[i]
访问越界 w1[i]
访问越界 z1[i]
访问越界 w1[i]
访问越界 z1[i]
访问越界bounds w1[i]
access out of bounds z1[i]
access out of bounds w1[i]
access out of bounds z1[i]
access out of bounds w1[i]
malloc(): invalid size (unsorted)
Aborted (core dumped ) )
推荐阅读
- r - 跨数据帧计算函数
- python - 使用 tkinter 单击按钮接收输入,然后返回我输入的任何内容,以便能够将其传递给其他函数
- google-bigquery - BigQuery 根据条件更新嵌套表
- httprequest - 带有正文的 HttpRequest DELETE
- npm - 如何运行 npm.cmd?
- sockets - TCPDUMP,tcp 标志未从标志 [S] 更改为其他标志值
- react-data-grid - 为什么这些 react-data-grid 列不能调整大小?
- python-3.x - 使用 zmq.Poller() 为我的 REQ/REP zmqclient 添加超时,但该函数不返回任何内容
- python - 如何使用硒从列表中选择一个项目?
- javascript - 在 Javascript Promise 中返回 'resolve' 函数