C - экспоненциальная функция вызывает segfault с файлом IO - PullRequest
0 голосов
/ 18 ноября 2011

РЕДАКТИРОВАТЬ: Чтобы ответить на некоторые вопросы, это пересмотренный и до сих пор не работает код (большая часть была там с самого начала, но я должен был четко указать, что я инициализировал указатель файла и т. Д.).Опять же, работает, только если я добавляю запись перед exp () или удаляю exp () полностью:

FILE *outfile;
char *outfilename;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
strcpy(outfilename, "outfile.txt");
outfile = fopen(realoutfilename, "w");

/* If this is uncommented, there isn't a segfault
if(realoutfile!=NULL && imoutfile!=NULL){
    fprintf(outfile, "\r\n");
    fseek(outfile,0,SEEK_SET);
}
*/

gauss = (double*) calloc(points, sizeof(double));

/* Maths and stuff */

if(outfile!=NULL){
    for(i=0;i<points;i++){
        /* this prints fine */
        printf(outfile, "%g,\r\n", gauss[i]);
        /* Seg fault is here */
        fprintf(outfile, "%g,\r\n", gauss[i]);

    }
}
fclose(outfile);
free(outfile);

И я компилирую с:

gcc main.c -lm -Wall -Wextra -Werror -Wshadow -g -o main

Для пояснения, это не доходит до конца функции - так что это не освобождение, при котором происходит сбой.Сбой происходит, когда он пытается записать в файл в цикле for.

Я проверил, что exp () не переполнен или не исчерпан, как я уже сказал, я могу напечатать вывод, но запись файланет-нет.Также произойдет сбой, если я попытаюсь сделать простой вызов, скажем, exp (2).

Обратный след GDB (я не очень знаком с GDB, думал, что это может помочь):

#0  0xff15665c in _malloc_unlocked () from /lib/libc.so.1
#1  0xff15641c in malloc () from /lib/libc.so.1
#2  0xff1a8c80 in _findbuf () from /lib/libc.so.1
#3  0xff1a8f0c in _wrtchk () from /lib/libc.so.1
#4  0xff1ad834 in _fwrite_unlocked () from /lib/libc.so.1
#5  0xff1ad798 in fwrite () from /lib/libc.so.1
#6  0x000128ac in gaussian ()
#7  0x00010f78 in main ()

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

4 голосов
/ 18 ноября 2011

Проблема здесь:

outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
outfilename = "file.txt";

Вы не можете назначить такую ​​строку, вы должны использовать strcpy:

strcpy(outfilename, "file.txt");

Что происходит, когда выперезаписываем указатель outfilename строковым присваиванием.Затем вы пытаетесь освободить его free(outfilename);.Поскольку вы освобождаете строковый литерал, поведение не определено, поэтому вы получаете сбой.

Что касается причины сбоя в одном случае, а не в другом.Поведение не определено, поэтому все может происходить.Вполне возможно, что ваш экспоненциальный код функции делает что-то со стеком / кучей, что может привести к его падению / не падению.

РЕДАКТИРОВАТЬ: Я надеюсь, что это просто опечатка или ошибка, ноЯ также не вижу, где инициализируется outfile.Если это действительно никогда не инициализируется, то это другая ошибка.(и, скорее всего, тот, который вызывает ваш конкретный segfault)

Так это должно выглядеть так:

FILE *outfile;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
strcpy(outfilename, "file.txt");

outfile = fopen(outfilename, "w");
if (outfile == NULL){
    //  Error, file cannot be openned.
}
1 голос
/ 18 ноября 2011
outfilename = "file.txt";
/* snip */
free(outfilename);

Вы можете освободить только то, что получили от malloc. Вы не можете передать free указатель на константу!

1 голос
/ 18 ноября 2011

Во-первых, вам действительно нужно скомпилировать с все предупреждения, включенные и с отладочной информацией, полученной ; с gcc это означает -Wall -g flags.

FILE *outfile;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
outfilename = "file.txt";

Вы должны использовать strdup, и я не вижу звонка на fopen например

 outfile = fopen(outfilename, "r");

И вы должны научиться использовать отладчик gdb (или, возможно, его ddd графический интерфейс).

...