Hi there, I'm fairly new to this C++ thing so I hope you can help.

I'm writing a program that prints out the coordinates of atoms in a simulation box (30x30x30). I have a fair few header and .cpp files so I'll only paste the bits that are faulty. I basically set up a subroutine to print out the coordinates of the atoms, and then use a loop and a random number generator to "insert" particles into that box. Here's the code:

    // Subroutine to print a PDB of the coordinates

    void print_pdb(double **coords, const int simbox_TotalNparticles, const int move)
{
    char filename[128];

    sprintf_s(filename, 128, "output%000006d.pdb", move);

    FILE *f = fopen(filename, "w");

    fprintf(f, "CRYST1 %8.3f %8.3f %8.3f  90.00  90.00  90.00\n", 
               sim_box[0], sim_box[1], sim_box[2]);

    for (int i = 0; i < simbox_TotalNparticles; i = i + 1)
    {
        fprintf(f, "ATOM  %5d  Methane   Methane     1    %8.3f%8.3f%8.3f  1.00  0.00          Methane\n",
                       i+1, coords[i][0], coords[i][1], coords[i][2]); 
        fprintf(f, "TER\n");

    }

    fclose(f);
}

int main()
{
 // Random variables and other

double **coords = new double*[simbox_TotalNparticles];

int seedmain;

        // Random seed
        srand ( (unsigned int)time(NULL) );
        seedmain=1; //time(NULL);

        // Starts the seqeunce of randon numbers
        CRandomMersenne RanGen(seedmain);
        CRandomMersenne *pRanGen;
        pRanGen=&RanGen;
        double random=RanGen.Random();

    // Randomly generate the coordinates of the atoms in the box
       for (int i = 0; i < simbox_TotalNparticles ; i = i + 1)
    {
        coords[i] = new double[3];

    // Note "random(0,x)" would generate a random number
    // between 0 and $x
        coords[i][0] = random*sim_box[0];
        coords[i][1] = random*sim_box[1];
        coords[i][2] = random*sim_box[2];

    //  Print the initial PDB file

        print_pdb(coords, simbox_TotalNparticles, 0);
        cin.ignore();

       }
       return (0);
}

It should be pointed out that the problem lies with the print_pdb function. The other variables you see there are defined in other files. When I debug the program I get the following message:

"Unhandled exception at 0x775415de in new.exe: 0xC0000005: Access violation reading location 0xcdcdcddd."

It should be noted that if I comment out the final "// Print the initial PDB file" part at the end the program runs successfully.

Any ideas?
Cheers

You need to take that call to print_pdb out of the loop that it's in (move it after line 59). print_pdb trys to loop over simbox_TotalNparticles elements and print them out, but they don't all exist yet.

You allocate your array of pointers to doubles on line 29. You then start looping over each element of this array on line 44. Each time you loop, you allocate the memory for the actual coordinates in that element and give them random values. So, one the first iteration of the loop you have an array of pointers of size simbox_TotalNparticles, the first element of that array points to another array of size 3 that contains random doubles (your coordinates). The remaining elements of the array are unitinialised. So, when you call print_pdb on line 56 and pass in simbox_TotalNparticles as the size, the loop on line 14 attempts to loop over all the elements of coords. Except for the first element, all the elements of coords are uninitialised, so you crash.

If I were you, I would do two things: firstly, make a Coord struct or class:

struct Coordinate
{
    double x;
    double y;
    double z;
};

Secondly, use a std::vector to store these structs:

std::vector< Coordinate > coords( simbox_TotalNparticles );

Now, you can let std::vector manage all the memory and tell you the size of things, so you will always avoid this kind of crash, and the memory-leak that your code will have if you don't remember to call delete[] on all of the elements of your coords array.

You will then be able to make your print_pdb class like this:

void print_pdb( const std::vector< Coordinate >& coords )
{
    for ( size_t i = 0; i < coords.size(); ++i ) {
        /std::cout << coords[ i ].x << " " << coords[ i ].y << " " << coords[ i ].z << std::endl;
    }
}

I just made this print to stdout, but you'll want to print in PDB format.

Hope that helps :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.