mardi 5 mai 2015

Probable stack overflow on passing a double pointer array

The 1st loop in the method monteCarlo() is running different times on different runs; after which it crashes returning 0xc0000005. So I'm guessing it's probably a stack overflow issue?

In the main function, I'm calling monteCarlo() several times. But not even one run is being completed because of the above issue.

However, if I comment out all the lines involving the double pointer array lattice inside the aforementioned loop in monteCarlo(), the issue disappears.

Initially I thought that lattice is getting passed by value, and multiple creations of the double pointer array is clogging up the memory. However, lattice is getting passed by reference, as can be seen in main() when I print lattice after passing it to initializeLattice() and modifying it there.

This is very frustrating, and I'm completely at a loss.

Thanks in advance.

# include <math.h>
# include <stdlib.h>
# include <stdio.h>
# include <time.h>


double energyContribution(int spin, int x, int y, int xLen, int yLen, int **lattice, double exchangeIntegral, double H);
double generateRandom(int lwr, int upr);
void initializeLattice(int xLen, int yLen, int **lattice);
double monteCarlo(int xLen, int yLen, int **lattice, double B, double H, double exchangeIntegral, double kB, double T);
void printLattice(int xLen, int yLen, int **lattice);


int main(void)
{
    int i,
        xLen = 10,
        yLen = 10,
        **lattice;

    double M,
           B = 0,
           H = 5.788 * pow(10, -5) * B, // eV
           exchangeIntegral = 1, // eV
           kB = 8.617 * pow(10, -5), // eV / K
           T = 1; // K;

    FILE *f1;

    srand(time(NULL));

    lattice = (int**) calloc(xLen, sizeof(int*));

    for(i = 0; i < xLen; i++)
    {
        lattice[i] = (int*) calloc(yLen, sizeof(int));
    }

    initializeLattice(xLen, yLen, lattice);

    printLattice(xLen, yLen, lattice);


    f1 = fopen("2DIsingModel_MonteCarlo_MvsT.txt", "w");

    while(T <= 10)
    {
        M = monteCarlo(xLen, yLen, lattice, B, H, exchangeIntegral, kB, T); printf("%lf\n", T);

        fprintf(f1, "%lf \t %lf\n", T, M);

        T += 1;
    }

    fclose(f1);

    return 0;
}


double energyContribution(int spin, int x, int y, int xLen, int yLen, int **lattice, double exchangeIntegral, double H)
{
    double E = 0;

    E += (x > 0)? (spin * lattice[x-1][y]): 0;
    E += (x < xLen-1)? (spin * lattice[x+1][y]): 0;

    E += (y > 0)? (spin * lattice[x][y-1]): 0;
    E += (y < yLen-1)? (spin * lattice[x][y+1]): 0;

    E *= -exchangeIntegral;

    E += -H * spin;

    return E;
}


double generateRandom(int lwr, int upr)
{
    double r;

    r = lwr + (double)rand() / (double)RAND_MAX * (upr - lwr);

    return r;
}


void initializeLattice(int xLen, int yLen, int **lattice)
{
    int i, j;

    double r;

    for(i = 0; i < xLen; i++)
    {
        for(j = 0; j < yLen; j++)
        {
            //r = generateRandom(0, 1);

            //lattice[i][j] = (r < 0.5)? 1: -1;

            lattice[i][j] = 1;
        }
    }
}


double monteCarlo(int xLen, int yLen, int **lattice, double B, double H, double exchangeIntegral, double kB, double T)
{
    int i, j, count = 0, c = 0,
        x, y;

    double Ei, Ef, dE, probability, r;

    FILE *f1, *f2;

    for(i = 0; i < 100000; i++)
    {
        x = round(generateRandom(0, xLen));
        y = round(generateRandom(0, yLen));

        printf("monteCarlo loop run: %d\n", i);

        Ei = energyContribution(lattice[x][y], x, y, xLen, yLen, lattice, exchangeIntegral, H);
        Ef = energyContribution(0-lattice[x][y], x, y, xLen, yLen, lattice, exchangeIntegral, H);

        dE = Ef - Ei;

        if(dE < 0)
        {
            lattice[x][y] = 0 - lattice[x][y]; //printf("xxx\n");
        }

        else if(dE > 0)
        {
            probability = exp(-dE / (kB*T));
            r = generateRandom(0, 1); //printf("%lf %e%\n", r, dE);

            lattice[x][y] = (r < probability)? (0 - lattice[x][y]): lattice[x][y];
        }
    }

    f1 = fopen("2DIsingModel_MonteCarlo_LatticeUp.txt", "w");
    f2 = fopen("2DIsingModel_MonteCarlo_LatticeDown.txt", "w");

    for(i = 0; i < xLen; i++)
    {
        for(j = 0; j < yLen; j++)
        {
            if(lattice[i][j] > 0)
            {
                fprintf(f1, "%d \t %d \t %d \n", i, j, lattice[i][j]);
                count++;
            }

            else
            {
                fprintf(f2, "%d \t %d \t %d \n", i, j, lattice[i][j]);
            }
        }
    }

    fclose(f1);
    fclose(f2);

    return (2*count) - xLen*yLen;
}


void printLattice(int xLen, int yLen, int **lattice)
{
    char *spacing;

    int i, j;

    for(i = 0; i < xLen; i++)
    {
        for(j = 0; j < yLen; j++)
        {
            spacing = (lattice[i][j] == 1)? "  ": " ";

            printf("%s%d", spacing, lattice[i][j]);
        }

        printf("\n");
    }
}

Aucun commentaire:

Enregistrer un commentaire