【问题标题】:C++ ROOT: ROOT closes when I try to open a file and read input from itC++ ROOT:当我尝试打开文件并从中读取输入时,ROOT 关闭
【发布时间】:2020-12-19 00:24:01
【问题描述】:

我正在使用 CERN ROOT 6.22/00(根据课程的要求)。我正在尝试读取包含两列数据的“输入文件”,如下所示:

40000 1397251483
40000 1397251484
40010 1397251485
40012 1397251486
40004 1397251487
40003 1397251488
40014 1397251489

这是产生错误的代码的最低可重现版本:

# include <iostream> // Header that defines the standard input/output stream objects:
# include <fstream> // Input/output stream class to operate on files.
# include <math.h> // Header declares a set of functions to compute common mathematical operations and transformations.
# include <iomanip> // Header providing parametric manipulators.

using namespace std;
int main()
{

    ifstream inFile;
        cout << "TEST";
    
    int NumOfRows = 1131635;
    char inputFileName[30] = "input.dat"; //File with the model parameters
    char outputFileName[30] = "output.dat";
    
    const int nArray = NumOfRows + 1;
    
    double paramOne[nArray];
    double T[nArray];
    
    //Reading input parameters from file into arrays//
    
    inFile.open(inputFileName,ios::in);
    
    return 0;

}

但是,当我继续运行此代码时,ROOT 退出,我又回到了终端。我也尝试使用g++ 运行代码,但出现错误:

Segmentation fault (core dumped)

有什么建议吗?

编辑:所以我继续将数组转换为向量,如下所示:

// V2: converted arrays to vectors to avoid memory problems

# include <iostream> // Header that defines the standard input/output stream objects:
# include <fstream> // Input/output stream class to operate on files.
# include <math.h> // Header declares a set of functions to compute common mathematical operations and transformations.
# include <iomanip> // Header providing parametric manipulators.

using namespace std;
int main()
{

    ifstream inFile;
    
    int NumOfRows = 10;
    char inputFileName[30] = "input.dat"; //File with the model parameters
    char outputFileName[30] = "output.dat";
    
    vector<int> TDC;
    vector<int> T;
    
    //Reading input parameters from file into arrays//
    
    inFile.open(inputFileName,ios::in);
    

    // Warning if file cant be opened
    if(!inFile.is_open()){ 
        cout << "Error opening file. \n";
        //cout << "Giving Retry... \n";
    }
    if(inFile.is_open()){
        cout<<"Input File was opened successfully"<<endl;
    }
    if(inFile.good()){
        cout<<"Input File is ready for reading"<<endl;
    }
    
    cout<< fixed;

    int rejects = 0;
    
    
    //reading file
    if(inFile.is_open()){
    
        // Putting cursor at start of file
        inFile.clear();
        
        //Reading first line
        inFile >> TDC[0] >> T[0];
        cout<<"TDC time"<<setw(15)<<"timestamp"<<endl;
        cout<<TDC[0]<<setw(20)<<T[0]<<endl;
}
    return 0;

}

目前我仍然面临内存问题:

Input File was opened successfully
Input File is ready for reading

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007fdc11e1d6e7 in waitpid () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007fdc11d88107 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007fdc129bfed3 in TUnixSystem::StackTrace() () from /home/nick/root/lib/libCore.so.6.22
#3  0x00007fdc129c29c5 in TUnixSystem::DispatchSignals(ESignals) () from /home/nick/root/lib/libCore.so.6.22
#4  <signal handler called>
#5  0x00007fdc1243d8c8 in std::istream::operator>>(int&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007fdc1320eab8 in ?? ()
#7  0x0000558f085c6f00 in ?? ()
#8  0x0ab62774202a8500 in ?? ()
#9  0x0000000000000000 in ?? ()
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum http://root.cern.ch/forum
Only if you are really convinced it is a bug in ROOT then please submit a
report at http://root.cern.ch/bugs Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007fdc1243d8c8 in std::istream::operator>>(int&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007fdc1320eab8 in ?? ()
#7  0x0000558f085c6f00 in ?? ()
#8  0x0ab62774202a8500 in ?? ()
#9  0x0000000000000000 in ?? ()
===========================================================

编辑 2:使用建议的解决方案:

// V2: converted arrays to vectors to avoid memory problems

# include <iostream> // Header that defines the standard input/output stream objects:
# include <fstream> // Input/output stream class to operate on files.
# include <math.h> // Header declares a set of functions to compute common mathematical operations and transformations.
# include <iomanip> // Header providing parametric manipulators.

using namespace std;
int main()
{

    ifstream inFile;
    
    int NumOfRows = 1131636;
    char inputFileName[30] = "input.dat"; //File with the model parameters
    char outputFileName[30] = "output.dat";
    
    size_t reasonableTDCSize = 1131635;
    
    vector<int> TDC(NumOfRows);
    vector<int> T(NumOfRows);

    
    //Reading input parameters from file into arrays//
    
    inFile.open(inputFileName,ios::in);
    

    // Warning if file cant be opened
    if(!inFile.is_open()){ 
        cout << "Error opening file. \n";
        //cout << "Giving Retry... \n";
    }
    if(inFile.is_open()){
        cout<<"Input File was opened successfully"<<endl;
    }
    if(inFile.good()){
        cout<<"Input File is ready for reading"<<endl;
    }
    
    cout<< fixed;

    int rejects = 0;
    int tempTDC = 0;
    int tempT = 0;
    
    //reading file
    if(inFile.is_open()){
    
        // Putting cursor at start of file
        inFile.clear();
        
        //Reading first line
        inFile >> tempTDC >> tempT;
        TDC.push_back(tempTDC);
        T.push_back(tempT);
        cout<<"TDC time"<<setw(15)<<"timestamp"<<endl;
        cout<<TDC[0]<<setw(20)<<T[0]<<endl;
        
        
        for (int a = 1; a < NumOfRows; a++){
            inFile >> tempTDC >> tempT;
            if ( tempTDC >= 40000 )
            {
               ++rejects;
               break;
            }

            cout<<tempTDC<<setw(20)<<tempT<<endl;
            // Reading rest of file
            TDC.push_back(tempTDC);
            T.push_back(tempT);
            //cout<<Mod[a]<<setw(15)<<z[a]<<setw(15)<<x[a]<<setw(15)<<M[a]<<setw(15)<<L[a]<<setw(15)<<T[a]<<endl;
                
        }
        
        //To show last and first index only, have this line uncommmented and the cout line in loop commented
        cout<<TDC[NumOfRows-1]<<setw(20)<<T[NumOfRows-1]<<endl;
        
        // Close the file.
        inFile.close(); 
    }
    
    /*
    cout<< "Lines remaining " << NumOfRows - rejects << endl;
            
    if(!inFile.is_open()){
        cout<<"Input File closed successfully"<<endl;
    }
    
    cout<< "Timestamp difference between first and last line is: " << T[NumOfRows-1] - T[0] << endl;
    
    
    cout<<"Creating output file"<<endl;
    ofstream outFile(outputFileName);
    outFile<<"TDC time"<<setw(15)<<"timestamp"<<endl; //Header
        for (int a = 1; a < NumOfRows; a++){
            
            // Reading rest of file
            outFile << TDC[a] << T[a];

                
        }
    outFile<<""<<endl;
    
        // Warning if file cant be opened
    if(!outFile.is_open()){ 
        cout << "Error opening file. \n";
        //cout << "Giving Retry... \n";
    }
    if(outFile.is_open()){
        cout<<"Output File was opened successfully"<<endl;
    }
    if(outFile.good()){
        cout<<"Output File is ready for reading"<<endl;
    }
    outFile.close();
    
    if(!outFile.is_open()){
        cout<<"Output File closed successfully"<<endl;
    }
    
    */
    return 0;

}

【问题讨论】:

  • 您在堆栈上分配了相当多的内存。如果您不使用那么大的数组,或者至少将它们移出堆栈,会发生什么?
  • @StephenNewell 当我将数组大小减小到 100000 时,代码按预期运行。我需要使用那么大的数组来读取我的数据文件中的所有行,因为我将输出和绘制这些数据。有没有办法解决这个问题?
  • 使用std::vector。这会将您的数据放在堆上。
  • @StephenNewell 所以我继续将我的数组重写为向量。我如何将文件中的数据直接读取到我的向量中,就像我如何将inFile &gt;&gt; TDC[0] &gt;&gt; T[0]; 用于数组一样?我会这样写吗:inFile &gt;&gt; TDC.push_back() &gt;&gt; T.push_back()
  • 无论如何你都在使用root。作为将数据从堆栈移动到堆的替代方法,您还不如在文件系统上的文件中使用 TTree,并让 root 负责将数据保留在内存之外。

标签: c++ root-framework


【解决方案1】:

在改进的版本(“V2”)中,您需要适当地调整向量的大小。

你可以这样做:

size_t reasonableTDCSize = /* some value */;
size_t reasonableTSize = /* some value */;

vector<int> TDC(reasonableTDCSize);
vector<int> T(reasonableTSize);

我不太明白你想做什么,但你可以,例如,做:

vector<int> TDC(NumOfRows);
vector<int> T(NumOfRows);

... if 这在语义上是有意义的。 正确调整它们的大小后,您的代码就可以工作了。

【讨论】:

  • 也许,我的描述似乎不完整,因为我尝试简化代码以重现错误。我已经包含了我的代码的完整版本。基本上,我想读取一个包含两列和 1131635 行的数据文件,将所有这些值存储在某个变量中,以便我可以将它们绘制成直方图,并将这些列写入另一个文件。
  • 如果我没有正确调整它的大小,向量中的所有值都会变为零?因为这就是我现在打印第一个和最后一个向量值时发生的情况。
  • 确切地说,向量从零开始。您应该将您期望的行数传递给构造函数,例如 vector&lt;int&gt; TDC(NumOfRows) 等。您也可以稍后使用 TDC.resize(new_size) 调整向量的大小。
猜你喜欢
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 2011-05-11
  • 2010-09-05
  • 2023-04-04
  • 1970-01-01
  • 2021-05-13
相关资源
最近更新 更多