首页 > 解决方案 > 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();
}

标签: c++

解决方案


将边界检查添加到您的代码中,您会看到您在很多地方访问数组越界。

...
// 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 ) )


推荐阅读