Search code examples
csegmentation-faultstack-overflow

What's causing segmentation fault in this program?


Please help me with this SIGSEGV error from calling the function below in my program:

int* calculateFitness(int** population, int** townDistancesMatrix, int chromoSize){
    int sum = 0;
    static int* Fitnesses;
    Fitnesses = malloc(sizeof(int)*chromoSize); 
    for(int i=0; i<chromoSize; i++){
        int indexOne = 0;
        int indexTwo = 0;
        for(int j=0; j<chromoSize-1; j++){
            indexOne = population[i][j];
            indexTwo = population[i][j+1];
            //printf("\n%d %d",indexOne-1,indexTwo-1);
            sum += townDistancesMatrix[indexOne-1][indexTwo-1];
        }
        indexOne = population[i][0];
        sum += townDistancesMatrix[indexTwo-1][indexOne-1];
        Fitnesses[i] = sum;
        sum = 0;
    }
    return Fitnesses;
}

Program runs without problem for smaller inputs(like 5 towns) so I first doubted that it was a stackoverflow, because program always runs for sometime (until similar value of i for all runs (i=20)) and then stops running and gives this error(in GDB):

Program received signal SIGSEGV, Segmentation fault. 0x0000000008000b9b in calculateFitness (population=0x7ffffffedcd0, townDistancesMatrix=0x8403470, chromoSize=48) at Untitled1.c:97 97 sum += townDistancesMatrix[indexOne-1][indexTwo-1];

However, I have no recursive function calls in calculateFitness so I thought maybe it was caused by large local variables in my function, but the local variables are few and small and my arrays are also created dynamically and don't go on stack(Maybe the problem is with my nested loop?).

I also ran valgrind (although I'm not yet very familiar with its reports and I just use it to get some hints) and here's the report:

==198== error calling PR_SET_PTRACER, vgdb might block
==198== Use of uninitialised value of size 8
==198==    at 0x108B41: calculateFitness (Untitled1.c:92)
==198==    by 0x108866: main (Untitled1.c:29)
==198==
==198== Use of uninitialised value of size 8
==198==    at 0x108B6E: calculateFitness (Untitled1.c:93)
==198==    by 0x108866: main (Untitled1.c:29)
==198==
==198== Invalid read of size 4
==198==    at 0x108B9B: calculateFitness (Untitled1.c:97)
==198==    by 0x108866: main (Untitled1.c:29)
==198==  Address 0x522d43c is 4 bytes before a block of size 192 alloc'd
==198==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck- 
amd64-linux.so)
==198==    by 0x108A56: readDistances (Untitled1.c:74)
==198==    by 0x1087EB: main (Untitled1.c:19)
==198==
==198== Invalid read of size 8
==198==    at 0x108B87: calculateFitness (Untitled1.c:97)
==198==    by 0x108866: main (Untitled1.c:29)
==198==  Address 0x522d278 is 8 bytes before a block of size 384 alloc'd
==198==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck- 
amd64-linux.so)
==198==    by 0x108A20: readDistances (Untitled1.c:71)
==198==    by 0x1087EB: main (Untitled1.c:19)
==198==
==198==
==198== Process terminating with default action of signal 11 (SIGSEGV)
==198==  Access not within mapped region at address 0xFFFFFFFFFC000018
==198==    at 0x108B9B: calculateFitness (Untitled1.c:97)
==198==    by 0x108866: main (Untitled1.c:29)
==198==  If you believe this happened as a result of a stack
==198==  overflow in your program's main thread (unlikely but
==198==  possible), you can try to increase the size of the
==198==  main thread stack using the --main-stacksize= flag.
==198==  The main thread stack size used in this run was 8388608.

//...

==198== LEAK SUMMARY:
==198==    definitely lost: 0 bytes in 0 blocks
==198==    indirectly lost: 0 bytes in 0 blocks
==198==      possibly lost: 0 bytes in 0 blocks
==198==    still reachable: 13,632 bytes in 70 blocks
==198==         suppressed: 0 bytes in 0 blocks

I searched parts of this error like "still reachable" and it seems not to be something I need to pay attention to, but I'm not sure about the meaning of first parts even after searching them. What am I doing wrong? If it's really a stackoverflow, what are other causes of a stackoverflow other than recursions?


Solution

  • int main(){
      int* population[POPSIZE];
    

    and

    for(int i=0; i<chromoSize; i++){
        int indexOne = 0;
        int indexTwo = 0;
        for(int j=0; j<chromoSize-1; j++){
            indexOne = population[i][j];
            indexTwo = population[i][j+1];
    

    You access out of population (signaled by valgrind), the value 48 you give to chromo_size (initializing chromoSize above) from your input file is too large with POPSIZE equals to 20

    After indexOne and indexTwo have random value so the accesses of townDistancesMatrix produces the seg fault signaled by valgrind

    In main after the scanf("%d",&chromo_size); check the value is <= POPSIZE to avoid that problem, and increase POPSIZE to be able to run with your input file


    Note also the free(population) is illegal because population is a local variable, it is not allocated in the heap