#c #root-framework
#c #root-framework
Вопрос:
Я использую 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>>(intamp;) () 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>>(intamp;) () 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;
}
Комментарии:
1. Вы выделяете довольно много памяти в своем стеке. Что произойдет, если вы не используете массивы такого размера или, по крайней мере, не удаляете их из стека?
2. @StephenNewell Когда я уменьшаю размер массива до 100000, код выполняется, как ожидалось. Мне нужно использовать массивы такого размера, чтобы прочитать все строки в моем файле данных, поскольку я буду выводить и отображать эти данные. Есть ли способ обойти это?
3. Используйте
std::vector
. Это поместит ваши данные в кучу.4. @StephenNewell Итак, я пошел дальше и переписал свои массивы в виде векторов. Как бы я прочитал данные из моего файла непосредственно в мой вектор, точно так же, как я использовал
inFile >> TDC[0] >> T[0];
для массивов? Я бы написал это так:inFile >> TDC.push_back() >> T.push_back()
?5. Поскольку вы все равно работаете с root. в качестве альтернативы перемещению ваших данных из стека в кучу, вы также можете использовать TTree в файле в вашей файловой системе и позволить root позаботиться о сохранении данных из памяти.
Ответ №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);
… если это имеет смысл семантически.
Как только вы правильно определили их размер, ваш код работает.
Комментарии:
1. Возможно, мое описание показалось неполным, потому что я попытался упростить свой код, чтобы воспроизвести ошибку. Я включил полную версию своего кода. В принципе, я хочу прочитать файл данных из двух столбцов и 1131635 строк, сохранить все эти значения в некоторой переменной, чтобы я мог их гистограммировать, а также записать столбцы в другой файл.
2. И если я не правильно определю его размер, все значения в векторе будут равны нулю? Потому что это то, что происходит, когда я печатаю первое и последнее векторные значения на данный момент.
3. точно, векторы начинаются с нулевого размера. вы должны передать количество строк, которые вы ожидаете, конструктору, например
vector<int> TDC(NumOfRows)
и т.д. Вы также можете изменить размер вектора позже сTDC.resize(new_size)
.