Problem with Segmentation fault with whole pointer

Asked

Viewed 90 times

0

The program below attempts to reproduce a cellular automaton model. When I use "n" (number of cells) above 65 thousand, 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 returns Segmentation fault. The code is below and I am very grateful if you can help.

Note: My only achism about what may be going wrong is that the whole pointers "P2" and "P3" cannot be greater than 65 thousand.

Obs2: If you want to understand in depth this model, 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;
 }
  • Problem perfectly solved by Isac below. Very grateful!

1 answer

0


The error has to do with the size of the elements allocated in stack with int pos[n][k] and others, that crosses the limit and generates a Segmentation Fault.

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

To confirm the mentioned problem just change the constant n:

const int n = 100000; //elementos 

To 100 who sees that the Segmentation Fault vanishes soon.

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

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

For the case of the vector pos 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 it has a few C++ things such as #include <iostream>, or v==elemento among others. This means that you cannot compile the code presented in the question as C but only as C++, and for this reason I left the Casts us mallocs because they are mandatory in C++. If the goal is C++ then move and use the features it gives you that are much simpler and straightforward.

  • Thank you very much from my heart! I have skills in programming in python but for simulations I am being forced to work in C. May your help return in double joy to you! Hug!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.