/// Program adopted from https://cplusplus.com/forum/general/220937/ /* "Hello, I was recently running a self-made programm in C++ and I got the following message during execution in the command window: terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Afterwards I receive a Windows message saying that the programm stopped because I have not enough memory. Thing is I am using dynamic memory for the program and I am afraid I have done something wrong with it... Is there any change to fix this? thanks in advance " */ /* On linux, the program crashed: " Welcome to the C++ program for Molecular Dynamics simulation. Introduce how many particles you want to work with: 10000 Now choose the value of the parameter a>0 , associated to the temperature: 2.5 Include now the total number of time steps you want to take for the simulation: 100 The initial velocities have been allocated in a matrix. End of the program double free or corruption (!prev) Aborted (core dumped) " ============= YOUR ASSIGNMENT: ============== 1. Identify the cause(s) of the memory error (place your answer in comments) 2. Rewrite the program in modern C++ ("clean c++"). Instead of double**, use the following types for dynamically allocated 2D array: #include ... typedef std::unique_ptr double1d; // replaces double* typedef std::unique_ptr double2d; // replaces double** Follow the "RULE OF ZERO". Remove all uses of raw pointers and replace them with smart pointers and references. You must be careful to use a reference (matrix& or matrix&&) where appropriate. The resulting program cannot be less efficient than the original program was intended to be. This is the length of a "real world" program, though it's actually not that long. Most of what you need to replace is relatively straightforward. But be careful. For example, consider the void populate(double** m) function. Do not just change this to void populate(double2d m): because double2d is a unique_ptr, which means there must be a transfer of ownership (move) to the local m when the function is called. This means that whatever double2d you passed to it would be destroyed after the call! Instead, change the signature of this function to void populate(double2d& m); Mixing smart pointers with references is OK. Also uncomment the call to operator_testing() inside main when you've fixed the program. */ #include #include #include #include #include #define pi 3.14159265359897 using namespace std; ///// header for matrix struct matrix { private: double** the_matrix; int x; // rows int y; // columns public: matrix(); matrix(int rows,int cols); ~matrix(); double** alloc(int rows,int cols); void clean(); void printm(); double** getmatrix(); void trans(); int nrows(); int ncolumns(); double get(int row,int column); void fill(double value,int row,int column); void DOS_populate(); void flip(matrix& m,int row,int column); void populate(double** pp); void eye(); void zeros(); double trace(); void add(matrix& m); void subs(matrix& m); void multiply(matrix& m); void double_rand(double min,double max); }; // matrix header, implementations below //allocation of memory double** matrix::alloc(int rows,int cols){ x=rows; y=cols; double** new_matrix=new double*[x]; for(int i=0;i(x); for(int i=0;i(y); } return new_matrix; } */ //Cleaning memory /deallocate matrix::~matrix(){ for(int i=0;i>the_matrix[i][j]; } } } //flips values of a whole sector of the matrix void matrix::flip(matrix& m,int row,int column){ int frow;//final row int fcolumn;//final colum; frow=m.nrows(); fcolumn=m.ncolumns(); if ((fcolumn>y)||(frow>x)){ cout<<"Error: the matrix you are trying to insert is too big "<>Npart; Nmax=125000; //The maximum allowed size of the cube is 50x50x50 while(Npart>Nmax){ cout<<"Sorry, number of particles is too big, please reduce it "; cin>>Npart; } cout<<"Now choose the value of the parameter a>0 , associated to the temperature: "; cin>>a; while(a<0){ cout<<"Sorry, but the parameter 'a' needs to be positive, try again: "; cin>>a; } cout<>npt; //The initial positions and velocities of the particles. Lets use a Maxwell-Boltzmann distribution for the velocities, whereas the position of particles //should be occupying vertices of a cube in space. //Matrices of initial positions and positions at time t, and for velocities., and the matrix of relative distances between particles, relevant for the //forces acting over each individual particle matrix r0(Npart,3),rt(Npart,3),v0(Npart,3),vt(Npart,3); //,forces(Npart,Npart); //Generate the array of random velocities vpoint=v_rand_MB(Npart,a); //Generate matrix of random velocities components initiate_velocities(v0,vpoint); cout<<"The initial velocities have been allocated in a matrix. "<