Estoy usando CERN ROOT 6.22. Estoy leyendo ~ 1000000 filas de datos de un archivo. Siempre que el valor en la primera columna> = 40000, quiero continuar el ciclo sin leer los valores de esa fila en vectores. Aquí hay una versión mínima de mi código:

# include <iostream>
# include <fstream>
# include <math.h>
# include <iomanip>
# include <cmath>
# include <stdlib.h>
# include <cstdlib>
//# include <fstream.h>
# include <string.h>
# include <string>
//# include <dos.h> //For Sleep() 

int main(){
    
    //////Controls//////
    
    char inputFileName[50] = "FridayToAlmostTwoWeeksThursday.dat"; //Name of input file with raw muon data 
    
    int NumOfLines = 1131635; //Number of lines in the input file, used for array index
    int LimitForGood = 40000; //'Time' in which all 'good' data is under. Will only collect data that is under this limit
    
    //////Variables/////
    
    ifstream inFile;
    
    double time_temp;
    
    const int nArray = NumOfLines + 1;
    
    //double time[nArray];
    //double timestamp[nArray];
    vector<double> time;
    vector<double> timestamp;
    
    ////////////////////////
    //////Main Program//////
    
    
    inFile.open(inputFileName,ios::in);
    
    if(inFile.is_open()){
        cout<<"Input File was opened successfully"<<endl;
    }
    
    // Create temporary containers to read data into vectors
    double tempTime = 0;
    double tempTimestamp = 0;
    
    //Main loop filling arrays from file//
    inFile>>tempTime>>tempTimestamp;
    time.push_back(tempTime);
    timestamp.push_back(tempTimestamp);
    cout<<time.at(0)<<setw(20)<<timestamp.at(0)<<endl;
    
    for(int i = 1; i < NumOfLines; i++){
        
        //inFile>>time[i]>>timestamp[i];
        inFile>>tempTime>>tempTimestamp;
        if (tempTime < LimitForGood){
        time.push_back(tempTime);
        timestamp.push_back(tempTimestamp);
        cout<<time[i]<<setw(20)<<timestamp[i]<<endl;
        }
        
    } 
    cout << "Size of vectors: " << time.size() << endl;
    inFile.close();
    
    return 0;
    
}

Mi problema es que cada vez que uso 40000, tengo problemas de memoria:

 *** Break *** segmentation violation

Sin embargo, si utilizo un número más pequeño, como 400, el código funciona bien. ¿Existe una forma general de solucionar este problema de modo que aún pueda verificar valores por debajo de 40000? Tendré que usar valores grandes como estos en todo mi código.

c++
1
Woj 31 ago. 2020 a las 21:34

1 respuesta

La mejor respuesta

El problema está aquí:

for(int i = 1; i < NumOfLines; i++){        
    inFile>>tempTime>>tempTimestamp;
    if (tempTime < LimitForGood){
        time.push_back(tempTime);
        timestamp.push_back(tempTimestamp);
        cout<<time[i]<<setw(20)<<timestamp[i]<<endl;
    }        
} 

Antes del ciclo, ya empujó un elemento al vector, por lo que a partir de i=1 puede usar i como índice después de empujar otro elemento al ciclo. Hasta ahora, está bien, pero ya en la siguiente iteración te desvías de los rieles:

Si en la segunda entrada en el archivo tempTime < LimitForGood es false entonces no está empujando esa entrada. En la segunda iteración (la que lee la tercera entrada del archivo) del bucle i=2 pero todavía hay solo un elemento en el vector. La próxima vez que agregue uno al vector, i será un índice no válido.

Utilice back() en su lugar para obtener una referencia al último elemento:

for(int i = 1; i < NumOfLines; i++){        
    inFile>>tempTime>>tempTimestamp;
    if (tempTime < LimitForGood){
        time.push_back(tempTime);
        timestamp.push_back(tempTimestamp);
        cout << time.back() << setw(20) << timestamp.back() << endl;
    }        
} 

Puede haber otros problemas, pero la lectura de un índice no válido del vector puede salir mal durante un tiempo sin que se note hasta que intente acceder a una dirección de memoria que no pertenece a su proceso. De todos modos, eso son solo especulaciones, pero seguro que lo anterior estaba mal y acceder a un índice inválido del vector es un comportamiento indefinido, también conocido como "cualquier cosa puede suceder".

5
largest_prime_is_463035818 31 ago. 2020 a las 18:58