Why is my array being filled with a garbage value when I have initialized it?

Viewed 96

I am at a bit of a loss. I have instantiated an std::array <int,9> acceptances with 9 zeros manually plugged.

This is kind of a long snippet of code, but I do not know what else to do. I have highlighted everywhere I have printed out acceptances. For some reasons, acceptances[1] = garbage. I do not see why this is happening. Right now, I am simply reassigning the value, but now I am worried stuff like this might happen elsewhere.

Here is the code:

// INSTANTIATE SIMULATIONS VARIABLES

    int    step_number    {0};
    int    move_number    {0};  
    double sysEnergy      {0};
    bool   IMP_BOOL       {true}; 

    std::array <int,9>    attempts    = {0,0,0,0,0,0,0,0,0};
    std::array <int,9>    acceptances = {0,0,0,0,0,0,0,0,0}; 
    std::array <double,8> contacts    = {0,0,0,0,0,0,0,0}; 
    std::cout << "acceptances[1] = " << acceptances[1] << std::endl;
    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
    // Parse inputs... 
    // This command will take all of the above inputs and make sure they are valid. 
    InputParser ( dfreq, max_iter, r, positions, topology, dfile, efile, mfile, stats_file, lattice_file_read ); 

    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#

    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
    // ExtractNumberOfPolymers extracts the total number of chains in the input file. used to reserve vector [line 171] 
    const int N = ExtractNumberOfPolymers(positions); 
    
    // EXTRACT TOPOLOGY FROM FILE 
    std::array <double,13> info_vec {ExtractTopologyFromFile(topology)}; 

    // info_vec is the vector with all the information that constitutes the toplogy of the simulation
    // assign values from info vec to relevant variables 
    const int x             =  info_vec[0] ;
    const int y             =  info_vec[1] ; 
    const int z             =  info_vec[2] ; 
    const double T          =  info_vec[3] ; 
    const double frac       =  info_vec[12]; 
    std::array <double,8> E =  {info_vec[4], info_vec[5], info_vec[6], info_vec[7], info_vec[8], info_vec[9], info_vec[10], info_vec[11]}; 
    
    // initialize custom data structures 
    std::vector <Polymer> Polymers; 
    Polymers.reserve(N);

    std::vector <Particle*> LATTICE;
    LATTICE.reserve (x*y*z); 

    std::vector <int> solvation_shells; 
    solvation_shells.reserve(26*26*N); 

    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
    // OPENING TILES

    std::cout << std::endl;
    std::cout << "Preparing for take-off...\n\n" ; 
    std::cout << "Chemical information: " << std::endl;
    std::cout << "Number of polymers is " << N << ".\n\n";
    std::cout << "Geometric information about simulation cell: " << std::endl;
    std::cout << "x = " << x <<", y = " << y << ", z = "<< z << "." << std::endl << std::endl;
    std::cout << "Thermodynamic and energetic information about simulation: " << std::endl; 
    std::cout << "Temperature = " << T << "." << std::endl; 
    std::cout << "Emm_a = " << E[0] <<", Emm_n = " << E[1] << ", Ems1_a = "<< E[2] << ", Ems1_n = " << E[3] <<".\n";
    std::cout << "Ems2_a = " << E[4] <<", Ems2_n = " << E[5] << ", Es1s2_a = "<< E[6] << ", Es1s2_n = " << E[7] <<".\n";  
    std::cout << "Off to a good start. \n\n";
    std::cout << "--------------------------------------------------------------------\n" << std::endl;
    std::cout << "Running some more checks on input... \n\n" ; 
    std::cout << "acceptances[1] = " << acceptances[1] << std::endl;
    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
    
    // set timers for simulation set-up.  
    auto start = std::chrono::high_resolution_clock::now(); 
    auto stop = std::chrono::high_resolution_clock::now(); 
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds> (stop-start); 


    if ( !r ){
        std::cout << "Setting up the lattice from scratch! " << std::endl;
        SetUpLatticeFromScratch (&Polymers, &LATTICE, positions, frac, x, y, z);
    
        stop = std::chrono::high_resolution_clock::now(); 
        duration = std::chrono::duration_cast<std::chrono::milliseconds> (stop-start); 

        std::cout << "Solvation took " << duration.count () << " milliseconds." << std::endl;
        std::cout << "Cell has been solvated! \n\n" ;
    
        dumpPositionsOfPolymers(&Polymers, step_number, dfile); 
    }

    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#

    else {
        std::cout << "Setting up system from a restart file!" << std::endl;
        SetUpLatticeFromRestart (x, y, z, &Polymers, &LATTICE, &step_number, lattice_file_read, dfile, positions ); 
        
        stop = std::chrono::high_resolution_clock::now(); 
        duration = std::chrono::duration_cast<std::chrono::milliseconds> (stop-start); 

        std::cout << "System set-up took " << duration.count () << " milliseconds." << std::endl;
        std::cout << "Simulation cell has been made! \n\n" ;

    }
    
    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#
    //~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#

    // THERMODYNAMICS OF SET-UP
    std::cout <<"\nCalculating energy..." << std::endl;

    sysEnergy = CalculateEnergy(&Polymers, &LATTICE, &solvation_shells, &E, &contacts, x, y, z); 

    std::cout << "Energy of system is " << sysEnergy << ".\n" << std::endl;
    
    // if i am not restarting, i do not need to dump anything. All the information is already present. 
    if (!r) {
        dumpEnergy      (sysEnergy, step_number, &contacts, efile); 
        dumpOrientation (&Polymers, &LATTICE, step_number, mfile, x, y, z); 
    }
    
    else {
        dumpOrientation (&Polymers, &LATTICE, step_number, mfile, x, y, z);    
    }
    
    std::cout << "Initiation complete. We are ready to go. The engine will output information every " << dfreq << " configuration(s)." << std::endl; 
    std::cout << "Number of iteration to perform: " << max_iter << "." << std::endl;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    std::cout << "acceptances[1] = " << acceptances[1] << std::endl;
    acceptances[1] = 0; 
    std::cout << "acceptances[1] = " << acceptances[1] << std::endl;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

The output reads:

acceptances[1] = 0
.
.
.
acceptances[1] = 1079214080
acceptances[1] = 0

I don't get it. I am not touching acceptances, yet, somehow it is being corrupted in there somewhere. Why is this happening? I am using clang, an Apple M1, -mcpu=apple-m1.

1 Answers

I was losing my mind a bit. But yes, per the suggestion of @selbie, it was indeed a buffer overrun. It was in CalculateEnergy (critical!), of all places.

CalculateEnergy calls for &contacts, and contacts is a std::array <double,8>. In the implementation of CalculateEnergy, I had erroneously asked for the value stored in contacts[8]. Evidently, this is a position out of range of contacts. Because of this overflow and the no bounds checking that comes with the [] operator, acceptances was being corrupted. Maybe other things were being corrupted as well. Glad it has been caught.

I am going to stick to .at over [] in the testing phase of my software.

Thank you all!

Related