Manas Paldhe
Manas Paldhe

Reputation: 776

segmentation error (core dumped)

I'm having a problem in reading and writing a file. I'm reading data from input.txt, calculating (Bytelandian problem) and writing the result to a file.

If I remove the last section of the code,

    /*
    for ( input_counter=0; input_counter<no_of_cases; input_counter++)
    {
        sprintf(buffer, "%d", max[input_counter]);
    fputs(buffer, fw);                
    }   
    fclose(fw);
    */

everything works well (except that I am unable to write to a file). But I am able to compile and run the code.

However on including that code, I get the error "segmentation error (core dumped)". Any idea what might be happening?

    #include<stdio.h>  
    #include <stdlib.h>  

    int Calculate_max (int number){
        int counter;
        int store[number+1];
        store[0] = 0;
        if (number>=1){
            store[1] = 1;
        }
        if (number>=2){
            store[2] = 2;
        }

        for (counter=3; counter<=number; counter++){
            store[counter] = store [counter/2] +store[counter/3]+store[counter/4];
            if (store[counter]<counter){
               store[counter]=counter;
            } 
        }
        return store[number];
    }

    int main(void){
        int no_of_cases=0;
        int number[10];
        int max[10];
        int input_counter=0;
        char line [ 128 ];
        char buffer [ 16 ];
        FILE *fr= fopen ("input.txt", "rt");            /* declare the file pointer */
        FILE *fw= fopen ("output.txt", "W+");           /* declare the file pointer */
        if ( fr != NULL )
        {
            if ( fgets ( line, sizeof line, fr ) != NULL ) /* read a line */
        {   
            no_of_cases = atoi (line);
            //printf("no %d \n", no_of_cases);
        }       
        if (no_of_cases==0)
        {
            printf("No Cases!!");
        }
        else 
        {
            for ( input_counter=0; input_counter<no_of_cases; input_counter++)
            {
                if ( fgets ( line, sizeof line, fr ) != NULL ) 
            {
                number[input_counter] = atoi (line);
                //scanf (line, number[input_counter], "%d");
                //printf(" %s \n " , line);
                //fputs ( line, stdout ); 
            }              
            max[input_counter]= Calculate_max(number[input_counter]);
            //fwrite(max[input_counter],sizeof(int),1,fp);          
            //fprintf(fw, "%d \n", max[input_counter]);                
            printf("%d \n", max[input_counter]);                
           }            
            }
        fclose(fr); 
        }   
        /*
        for ( input_counter=0; input_counter<no_of_cases; input_counter++)
        {
            sprintf(buffer, "%d", max[input_counter]);
        fputs(buffer, fw);                
        }   
        fclose(fw);
        */
    return 0;
    }

The new code:

    #include<stdio.h>  
    #include <cstdlib>  
    long long Calculate_max ( long long number)
    {
    long long counter;
    long long store[number+1];
    store[0] = 0;
    if (number>=1){
        store[1] = 1;
    }
    if (number>=2){
        store[2] = 2;
    }
    for (counter=3; counter<=number; counter++){
        store[counter] = store [counter/2] +store[counter/3]+store[counter/4];
        if (store[counter]<counter){
            store[counter]=counter;
        }
    }
    return store[number];
    }         
    int main(void)
    {
    int no_of_cases=10;
    long long number;
    long long max[10];
int input_counter=0;
char line [128];
char buffer [ 64 ];
FILE *fr= fopen ("input.txt", "rt");            /* declare the file pointer */
FILE *fw= fopen ("output.txt", "w+");           /* declare the file pointer */
if ( fr != NULL )
{   
    while ( fgets ( line, sizeof line, fr ) != NULL ) 
        {
            //number= atoll (line);
            number=1000000000;              
            max[input_counter]= Calculate_max(number);
            input_counter++;
            printf("test \n");
        }              
    fclose(fr);
}   
printf("writing \n");
no_of_cases=input_counter;
for ( input_counter=0; input_counter<no_of_cases; input_counter++)
{
    sprintf(buffer, "%lld", max[input_counter]);        
    fputs(buffer, fw);                
    fputs("\n", fw);                
}   
fclose(fw); 
return 0;
    }

Upvotes: 0

Views: 2264

Answers (2)

Chimera
Chimera

Reputation: 6038

EDIT: Your new code is failing at store[0] = 0 in the Calculate_max() function because your number contains a value too large to create an array of that size of long longs on the stack.

As Adam suggested in his answer, you should use a debugger to help you determine where the code is causing the problem. I've gone ahead and done this for you so you can see how it's done. Hopefully you will find this useful.

Here is a debug session using GDB. You will see that the segmentation fault is caused at line 69:

fclose(fw);

The fix is to open the file using this line:

FILE *fw= fopen ("output.txt", "w+");

Notice that the w is now lower case.

[jrn@localhost ~]$ gcc -ggdb boom.c -o boom
[jrn@localhost ~]$ gdb boom
Reading symbols from /home/jrn/boom...done.
(gdb) run
Starting program: /home/jrn/boom 

Program received signal SIGSEGV, Segmentation fault.
0x00c0660d in fclose@@GLIBC_2.1 () from /lib/libc.so.6
(gdb) bt
#0  0x00c0660d in fclose@@GLIBC_2.1 () from /lib/libc.so.6
#1  0x08048759 in main () at boom.c:69

Upvotes: 3

Adam Rosenfield
Adam Rosenfield

Reputation: 400700

You should really be using a debugger here, it will tell you exactly which line of code is crashing.

I suspect that your problem is that the output file fw is failing to be opened, so the call to fputs(buffer, NULL) is crashing. You should be checking to make sure that the file is successfully opened, and if it isn't, bail out accordingly. It's likely failing to open since you're passing an invalid mode string of "W+".

Try just "w" (lowercase w, not uppercase), since you only need write access, you don't need read-write access (if you do, use "w+" instead).

Upvotes: 4

Related Questions