简体   繁体   中英

Why my program gets a segfault in linux-gcc but not on mingw-gcc?

I have written a program in C. The problem is when I compile this program in a Linux/Unix environment I get a segfault. But when I compile it in Windows with minGW It works fine. Basically in the program I have a multidimensional array. When I compile and debug in gdb in Linux/Unix I lose one row of the multidimensional array randomly. When I try to access every column in that row all of them suddenly cannot be accessed. My whole row gets lost.

Error:Program received signal SIGSEGV, Segmentation fault.

Note: isItDone(), oneToTwo(), and checkAroundTwo() are very likely not the problem. I tried running program without them and it still showed the error.

The code:

int main( int argc, char *argv[] ){
    FILE * output;
    output = fopen("output.txt", "w");
    srand(time(NULL));
    int size = 0; // Resetting before taking arguments
    int evaltime = 0; // Resetting before taking arguments
    int rand1, rand2;
    int counter, counter2, counter3;
    if(argc == 3){
        size = atoi(argv[1]);
        evaltime = atoi(argv[2]);
    }
    else{
        return 0;
    }
    double *evaltimes = (double*)calloc(evaltime , sizeof(double)); // The array of the results we got.
    for(counter2 = 0; counter2 < evaltime; counter2++){
        int cellnumbers = 0;
        int **ground = (int**)malloc(size * sizeof(int)); //Mallocating for every iteration
        for(counter = 0; counter < size; counter++){
            ground[counter] = (int*)calloc(size, sizeof(int)); // Initializing all the 0.
        }
        while(!isItDone(ground, size)){ // It's finished when last row is 2.
            rand1 = rand() % size;
            rand2 = rand() % size; // Take two random numbers for picking in array limit.
            printf("%d %d\n", rand1, rand2);
            if(rand1 == 0){ // Is it a top cell
                if(ground[rand1][rand2] == 0){
                    ground[rand1][rand2] = 2;
                    cellnumbers++; // Increment when a cell is picked.
                }
            }
            else{
                if(ground[rand1][rand2] == 1 || ground[rand1][rand2] == 2) // The cell is already opened
                    continue;
                else{
                    ground[rand1][rand2] = 1; // Defaulting to 1 before control
                    cellnumbers++;
                    oneTotwo(ground, size, rand1, rand2);
                }
            }
        }
        if(counter2 == evaltime - 1){ // Printing the last variation
            for(counter3 = 0; counter3 < size; counter3++){
                for(counter = 0; counter < size; counter++){
                    fprintf(output, "%d  ",ground[counter3][counter]);
                }
                fprintf(output, "\n");
            }
        }
        evaltimes[counter2] = (double)cellnumbers / (double)(size*size);
        for(counter = 0; counter < size; counter++)
            free(ground[counter]);

        free(ground);
    }
    double meany = mean(evaltimes, evaltime);
    double stddeviation = stddev(evaltimes, evaltime, meany);
    fprintf(output, "mean()  =  %f \n", meany);
    fprintf(output, "stddev()  =  %f",stddeviation);  
    fclose(output);
    return 0;
}

I think the bug is most likely lies in main but here are my functions.

int isItDone(int **p, int size){
    int counter;
    for(counter = 0; counter < size; counter++){
        if(p[size - 1][counter] == 2 && (p + size - 1) != 0)
            return 1;
    }
    return 0;
}

void oneTotwo(int **p, int size, int rand1, int rand2){
    //Checking the Upper Cells
    if(rand1 < size - 1){ // Making sure no control if it is the last cell.
        if(p[rand1 + 1][rand2] == 2){
            p[rand1][rand2] = 2;
            checkAroundTwo(p, size, rand1, rand2);
        }
    }
    if(rand1 > 0){
        if(p[rand1 - 1][rand2] == 2){
            p[rand1][rand2] = 2;
            checkAroundTwo(p, size, rand1, rand2);
        }   
    }
    if(rand2  < size - 1){
        if(p[rand1][rand2 + 1] == 2){
            p[rand1][rand2] = 2;
            checkAroundTwo(p, size, rand1, rand2);
        }
    }
    if(rand2 > 0){
        if(p[rand1][rand2 - 1] == 2){
            p[rand1][rand2] = 2;
            checkAroundTwo(p, size, rand1, rand2);
        }
    }
}

void checkAroundTwo(int **p, int size, int rand1, int rand2){
    if(rand1 < size - 1){
        if(p[rand1 + 1][rand2] == 1){
            p[rand1 + 1][rand2] = 2;
            checkAroundTwo(p, size, rand1 + 1, rand2);
        }
    }
    if(rand1 > 0){
        if(p[rand1 - 1][rand2] == 1){
            p[rand1 - 1][rand2] = 2;
            checkAroundTwo(p, size, rand1 - 1, rand2);
        }
    }
    if(rand2 < size - 1){
        if(p[rand1][rand2 + 1] == 1){
            p[rand1][rand2 + 1] = 2;
            checkAroundTwo(p, size, rand1, rand2 + 1);
        }
    }
    if(rand2 > 0){
        if(p[rand1][rand2 - 1] == 1){
            p[rand1][rand2 - 1] = 2;
            checkAroundTwo(p, size, rand1, rand2 - 1);
        }
    }
}

double mean(double *p, int size){
    double sum = 0.0000000;
    int counter;
    for(counter = 0; counter < size; counter++)
        sum += p[counter];

    return sum / (double)(size);
}

double stddev(double *p, int size, double mean){
    double sum = 0.0000000;
    int counter;
    for(counter = 0; counter < size; counter++)
        sum += sqr(((double)p[counter] - mean));

    return sqrt(sum / (double)(size - 1)); 
}

double sqr(double x){
    return x*x;
}

double sqrt(double x){
    int counter = 0;
    while(sqr(counter) < x){
        counter++;
    }
    double s = counter;

    for(counter = 0; counter < 50; counter++){
        s = (double)1/2 * (double)(s + x/s);
    }
    return s;
}

Let's assume int array[10][10] One more weird thing is that in gdb when I for example lose array[5] row I try to access it from the row before it. For example with array[4][10]. When I do it "array[4][10] = 49". Why is this? Rest is (array[4][12], array[4][13] etc.) is 0 as I specified. Why suddenly the first element of the 5th row achieved from the 4th row becomes 49 ? That I dont understand.

When you assign memory to a 2D array, you're assigning an array of pointers, each of which points to a block of memory.

This means when you do your initial malloc you need to assign ...sizeof(int*) and not ...sizeof(int) .

In short, change this line:

int **ground = (int**)malloc(size * sizeof(int));

to:

int **ground = (int**)malloc(size * sizeof(int*));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM