ошибка сегментации (дамп ядра)

У меня проблема с чтением и записью файла. Я читаю данные из input.txt, вычисляю (байтландская проблема) и записываю результат в файл.

Если я удалю последний раздел кода,

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

все работает хорошо (за исключением того, что я не могу писать в файл). Но я могу скомпилировать и запустить код.

Однако при включении этого кода я получаю сообщение об ошибке «ошибка сегментации (сброс ядра)». Любая идея, что может происходить?

    #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;
    }

Новый код:

    #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;
    }

person Manas Paldhe    schedule 19.09.2012    source источник
comment
Судя по сообщению об ошибке, вы используете Unix. Попробуйте отладчик gdb отследить вашу программу шаг за шагом, проверяя значения используемых переменных. Также вы можете передать ядро, которое было сброшено в gdb, и оно покажет вам, где произошло нарушение сегментации.   -  person alk    schedule 19.09.2012
comment
Скомпилируйте с отладочными символами, обычно используя флаг -g, и запустите его в отладчике. Это должно быть довольно очевидно.   -  person dmp    schedule 19.09.2012
comment
Новая ошибка кода теперь объясняется в моем ответе.   -  person Chimera    schedule 20.09.2012
comment
В какой-то момент вы, вероятно, захотите проголосовать и/или принять ответ, который помог вам больше всего.   -  person Chimera    schedule 20.09.2012


Ответы (2)


Вам действительно следует использовать здесь отладчик, он точно скажет вам, какая строка кода дает сбой.

Я подозреваю, что ваша проблема в том, что выходной файл fw не открывается, поэтому вызов fputs(buffer, NULL) дает сбой. Вы должны убедиться, что файл успешно открыт, и если это не так, выйдите из строя соответствующим образом. Скорее всего, он не откроется, поскольку вы передаете недопустимую строку режима "W+".

Попробуйте просто "w" (строчные w, а не прописные), так как вам нужен только доступ для записи, вам не нужен доступ для чтения-записи (если вы это сделаете, используйте вместо этого "w+").

person Adam Rosenfield    schedule 19.09.2012
comment
Добро пожаловать в StackOverflow! Если это решило вашу проблему, вы должны принять это как ответ. - person Adam Rosenfield; 19.09.2012

EDIT: ваш новый код дает сбой в store[0] = 0 в функции Calculate_max(), потому что ваш number содержит значение, слишком большое для создания массива такого размера long longs в стеке.

Как Адам предложил в своем ответе, вы должны использовать отладчик, чтобы определить, где код вызывает проблему. Я пошел дальше и сделал это для вас, чтобы вы могли видеть, как это делается. Надеюсь, вы найдете это полезным.

Вот сеанс отладки с использованием GDB. Вы увидите, что ошибка сегментации вызвана в строке 69:

fclose(fw);

Исправление заключается в том, чтобы открыть файл с помощью этой строки:

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

Обратите внимание, что буква w теперь в нижнем регистре.

[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
person Chimera    schedule 19.09.2012
comment
Я обновил код, чтобы включить long long. Теперь у меня ошибка в Calculate_max. Что означает эта ошибка (ошибка сегментации)? - person Manas Paldhe; 19.09.2012
comment
Ошибка сегментации означает, что вы записали в область памяти, которая была за пределами границ (вы ошиблись с недопустимым адресом). См. cprogramming.com/debugging/segfaults.html. - person Chimera; 19.09.2012
comment
Если вы найдете мой ответ полезным, пожалуйста, проголосуйте и / или примите ответ. Вот как вы вознаграждаете людей за помощь вам здесь. - person Chimera; 19.09.2012
comment
переход на w+ не помогает мне решить ошибку сегментации в случае long long. - person Manas Paldhe; 20.09.2012
comment
как я могу проголосовать за вас? Я принял ответ Адама, не показывает возможность принять ваш! - person Manas Paldhe; 20.09.2012
comment
Что ж, вы можете щелкнуть стрелку над 0, чтобы проголосовать за мой ответ. - person Chimera; 20.09.2012