Tentei dormir. Fiquei pensando sobre um problema por resolver e vim aqui "codar".
Ó:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void simula_mc(int L, int Nsteps, double temp, int **S, int **resultados, double *magnetizacao, double *energia);
void inicializa_matriz(int **S, int L);
void troca(int **S, int L, double temp);
void calcula(int **S, int L, int *mag, int *ener);
int main(int argc, char** argv){
	int L, Nsteps, counter, **S, **resultados;
	double temp, magnetizacao, energia;
	FILE *output;
	srand (1);
	/* Converte os parametros de entrada em variaveis utilizaveis */
	if (argc !=  5){
		printf("Erro: Uso: %s  L Nsteps temp outfile\n", argv[0]);
		exit(1);
	}
	L = atoi(argv[1]);
	Nsteps = atoi(argv[2]);
	temp = atof(argv[3]);
	
	/* Declara a matriz de Ising S*/ 
	S = malloc(L*sizeof(int*));
	if (S == NULL){
		printf("Allocation failure\n");
		exit (2);
	}
	for( counter=0; counter < L; counter++){	
		S[counter] = malloc(L * sizeof(int));
		if (S[counter] == NULL){
		printf("Allocation failure\n");
		exit (2);
		}
	}
	
	/* Declara a matriz de rezultados: primeira coluna = magnetizacao, segunda coluna = energia. uma linha por passo de MC */
	resultados = malloc(Nsteps*sizeof(int *));
	if (resultados == NULL){
		printf("Allocation failure\n");
		exit (2);
	}
	for( counter=0; counter < Nsteps; counter++){
		resultados[counter] = malloc(2 * sizeof(int));
		if (resultados[counter] == NULL){
		printf("Allocation failure\n");
		exit (2);
		}
	}
	
	simula_mc(L, Nsteps, temp, S, resultados, &magnetizacao, &energia);
	
	output = fopen(argv[4], "w");
	if (output == NULL){
		printf("Erro ao abrir arquivo %s para escrita\n", argv[6]);
		exit(2);
	}
	
	fprintf(output, "#Saida montecarlo: T = %g; %d passos; L = %d\n",temp, Nsteps, L);
	fprintf(output, "#Magnetizacao media: %g \t Energia media %g\n", magnetizacao, energia);
	fprintf(output, "#Passo\tMagnetizacao\tEnergia\n");
			
	for( counter=0; counter < Nsteps; counter++){
		fprintf(output, "%d\t%d\t%d\n", counter, resultados[counter][0], resultados[counter][1]);
	}
	
	fclose(output);	
	
	for(counter = 0; counter < L; counter++) free(S[counter]);
	free (S);
	
	for (counter = 0; counter < Nsteps; counter++) free(resultados[counter]);
	free(resultados);
	return 0;
}
void simula_mc(int L, int Nsteps, double temp, int **S, int **resultados, double *magnetizacao, double *energia){
	int passo, passoMC, L2 = L*L;
	int mag_passo, ener_passo;
	
	temp = 1/temp;
	*magnetizacao= 0;
	*energia = 0;
	inicializa_matriz(S, L);
	
	/* transiente */
	for (passo = 0; passo < L2*Nsteps/10; passo++)
		troca(S, L, temp);
	
	for (passoMC = 0; passoMC < Nsteps; passoMC++)
	{
		for(passo = 0; passo < L2; passo++)
			troca(S, L, temp);
		calcula(S, L, &mag_passo, &ener_passo);
		*magnetizacao += abs(mag_passo);
		*energia += ener_passo;
		resultados[passoMC][0]= mag_passo;
		resultados[passoMC][1]= ener_passo;
	}
	*magnetizacao = *magnetizacao/Nsteps;
	*energia = *energia/Nsteps;
}
void inicializa_matriz(int **S, int L){
	int i, j;
	for (i=0; i < L; i++)
		for (j=0; j < L; j++){
			S[i][j] = 1;
		}
}
void troca(int **S, int L, double temp){
	int i, j, imais, imenos, jmais, jmenos;
	int delta_E;
	double aleat;
		
	i = rand() % L;
	j = rand() % L;
	imais = (i+L+1)%L;
	imenos = (i+L-1)%L;
	jmais = (j+L+1)%L;
	jmenos = (j+L-1)%L;
	
	delta_E = 2 * S[i][j] * (S[i][jmais]+ S[i][jmenos] + S[imais][j] + S[imenos][j]);
	
	if(delta_E <= 0){
		S[i][j] *= -1;
	}
	else{
		aleat = (double) rand()/RAND_MAX;
		if (aleat < exp(-delta_E*temp)){
			S[i][j] *= -1;
		}
	}
}
void calcula(int **S, int L, int *mag, int *ener){
	register int i, j;
	*mag=0; *ener=0;
	for (i=0; i < L; i++){
		for (j=0; j < L; j++){
		    *mag += S[i][j];
		    *ener += S[i][j]*(S[i][(j+1)%L] + S[(i+1)%L][j]);
		}
	}
}