Problem with Segmentation fault with integer pointer

0

The program below attempts to reproduce a cellular automaton model. When I use "n" (number of cells) in excess of 65K, the program returns Segmentation fault.

I tried to "print" some text in several places of the code, but it does not execute (the print) and already it returns Segmentation fault. The code is below and I'm very grateful if you can help.

Note: My only guess about what may be going wrong is that the whole pointers "p2" and "p3" can not be greater than 65,000.

Obs2: If you want to understand this model in depth, it is described in this article: Optimal Dynamical Range of Excitable Networks at Criticality

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


#define myrand ((float)(random())/(float)(RAND_MAX) ) 

const int   estados_maximos = 10,
            tempo = 1000,
            k = 10; //numero fixo de pos

const int n = 100000; //elementos

const float porcent = 0.1;

int n_ativados_inicial = ceil(porcent*n); //arredonda para mais

double sigma = 1.05;



int Existe(int valores[],int tam,int valor){
    for(int i = 0;i<tam;i++){
        if(valores[i]==valor)
            return 1;
    }
    return 0;
}

void GeraAleatorios(int numeros[],int quantNumeros,int Limite,int elemento, int feliz){
    srand((unsigned)time(NULL) + 5865*feliz); // pode-se somar algo para mudar a semente


    int v;
    for(int i=0;i<quantNumeros;i++){
        v = rand() % Limite;
        while(Existe(numeros,i,v) or v==elemento){
        v = rand() % Limite;
        //printf("preso %d ", v);
        rand();
        }
        numeros[i] = v;
    }

}

int main() {
    int i, j, t, aux, *p2, *p3;
    int pos[n][k], contemplados[n_ativados_inicial], estados1[n], estados2[n], total_ativos[tempo+1];
    double P[n][k], pmax, *p;
    FILE *rho;
    char name[100];

    srand((unsigned)time(NULL));

    pmax = (double)2*sigma/k;


    p2=&estados1[0];
    for(i=0;i<n;i++){p2[i]=0;};

    //montar Pij
    p=P[0]; //apontar o ponteiro para o inicio de P
    for (i=0;i<n*k;i++)
    {p[i] = myrand*pmax;}

    GeraAleatorios(contemplados,n_ativados_inicial,n,n+10,1000);

    for(i=0; i<n_ativados_inicial; i++){estados1[contemplados[i]]=1;};
    total_ativos[0] = n_ativados_inicial;
    //gravar a quantidade de ativados inicialmente!
    t = 0;

    //arquivo
    sprintf(name,"rho_com_sigma_%3.2f.dat", sigma);
    rho = fopen(name,"w");

    p2=estados1;
    p3=estados2; 

    for(i=0; i<n; i++){p3[i]=p2[i];} */

while(t<tempo and total_ativos[t]!=0){
    //flag
    if(t%2){p2=estados2;
        p3=estados1;
        }
    else{
        p2=estados1;
        p3=estados2;
        };

    aux = 0;
    for(i=0; i<n; i++){
        switch(p2[i]){
            case 0:{ //falta adicionar o estimulo externo
                for(j=0; j<k; j++){
                    if(p2[pos[i][j]]==1 and P[i][j] > myrand){
                        p3[i]=1;
                        aux+=1;
                        break;
                        };
                        p3[i] = 0;
                    };
                break;
                }
            case (estados_maximos-1):{
                p3[i]=0;
                break;
                }

            default:{
                p3[i]=p2[i]+1;
                break;
            }

            } // fim do switch

        }; // fim do for

        t+=1;
        total_ativos[t] = aux;

        }; //fim do while

    //gravar o total de ativos em arquivo    
    for(i = 0; i<tempo+1;i++){
        fprintf(rho,"%d %lf\n",i,(double)total_ativos[i]/n);}
    fclose(rho);
     return 0;
 }
    
asked by anonymous 27.09.2018 / 21:09

1 answer

0

The error has to do with the size of the elements allocated in stack with int pos[n][k] and remaining, which passes the limit and generates a Segmentation Fault . >

You can try setting the stack size so that allocations do not go over the limit, but the most common solution is to dynamically allocate malloc " or in the case of c ++ with new . In dynamic allocation, the same limit is no longer imposed.

To confirm the above problem, simply change the constant n :

const int n = 100000; //elementos 

For 100 you see that Segmentation Fault disappears soon.

Exemplifying the solution by allocating with malloc to int estados1[n] would be:

int *estados1 = (int*)malloc(sizeof(int) * n);

Now for the case of the pos vector, it is more elaborate because it is a two-dimensional vector:

int **pos = (int**)malloc(sizeof(int*) * n);

for (int i = 0; i < n; ++i){
    pos[i] = (int*)malloc(sizeof(int) * k);
}

As an aside, the code you have is not pure C code, as there are a few C ++ things like #include <iostream> , or v==elemento , and so on. This means that I can not compile the code presented in the question as C but only as C ++, and for that reason I left the casts in mallocs because they are mandatory in C ++. If the goal is C ++ then go through and use the features that this gives you that are much simpler and direct.

    
28.09.2018 / 00:12