Ошибка Сег на fopen / fclose - PullRequest
       15

Ошибка Сег на fopen / fclose

1 голос
/ 13 июня 2011

У меня есть программа, которая создает несколько файлов.Существует функция для каждого создаваемого файла.Внутри каждой функции есть один и тот же код для создания имени файла, открытия / создания файла для записи, установки его прав доступа и в конце закрытия файла.Я решил создать функцию для открытия и закрытия файла, чтобы я мог просто вызывать ее, вместо того чтобы каждый раз использовать один и тот же код.Ранее код выглядел следующим образом в каждой функции:

void WriteFile1(char *name) {
   FILE *file;
   char *filename; //This is being malloc'ed because it initially consisted of multiple strings

   if (!(filename = malloc(sizeof(char *) * (strlen(name) + 1)))) MallocError();
   if (!(file = fopen(filename, "w"))) {
       fprintf(stderr, "Unable to open %s. Exiting \n", filename);
       exit(1);
   }
   fchmod(fileno(file), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH);

   //a bunch of fprintf statements here

   if (fclose(file)) {
       fprintf(stderr, "Error closing %s. Exiting...\n", filename);
       exit(1);
   }
}

Это прекрасно работало.У меня не было проблем.Теперь это выглядит следующим образом:

void WriteFile1() {
FILE *file;

OpenFile(file, "filename.asdf");
//fprintf statements
CloseFile(file, "filename.asdf");
}

void OpenFile(FILE *file, char *name) {
   if (!(file = fopen(name, "w"))) {
      fprintf(stderr, "Unable to open %s. Exiting... \n", name);
      exit(1);
   }
   fchmod(fileno(file), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH);
}
void CloseFile(FILE *file, char *name) {
    if (fclose(file)) {
        fprintf(stderr, "Error closing %s. Exiting...\n", name);
        exit(1);
    }
}

Он обнаруживает ошибки, как только я добираюсь до первого оператора fprintf в WriteFile1 ().Я делаю что-то неправильно с переменной FILE?Кажется, это должно работать так же, как и раньше.Единственная разница - это malloc строки имени файла, которую я вместо этого передаю как имя и даю фактическое значение в кавычках.

Спасибо

Ответы [ 3 ]

2 голосов
/ 13 июня 2011

Этот фрагмент кода неправильный:

void OpenFile(FILE *file, char *name) {
   if (!(file = fopen(name, "w"))) {

Здесь вы просто присваиваете локальную переменную file. Вы должны вернуть file, чтобы ваша функция WriteFile1 () могла работать с этим ФАЙЛОМ *

void WriteFile1() {
FILE *file;

file = OpenFile("filename.asdf");
//fprintf statements
CloseFile(file, "filename.asdf");
}

FILE * OpenFile(char *name) {
   FILE * file;
   if (!(file = fopen(name, "w"))) {
      fprintf(stderr, "Unable to open %s. Exiting... \n", name);
      exit(1);
   }
   fchmod(fileno(file), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH);
   return file;
}
1 голос
/ 13 июня 2011

Это:

filename = malloc(sizeof(char *) * (strlen(name) + 1))

должно быть:

filename = strdup(name);

, если у вас есть, в противном случае что-то вроде:

if((filename = malloc(strlen(name) + 1)) != NULL)
{
   strcpy(filename, name);
   ...
}

Обратите внимание, в частности, что каждый символэто просто char, а не char *.Поскольку sizeof (char) == 1 всегда верно, нет никакого смысла вовлекать его вообще.

1 голос
/ 13 июня 2011

Ваша открытая функция должна выглядеть следующим образом:

FILE *  OpenFile( char *name) {
   FILE * file;
   if (!(file = fopen(name, "w"))) {
      fprintf(stderr, "Unable to open %s. Exiting... \n", name);
      exit(1);
   }
   fchmod(fileno(file), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH);
   return file;
}

В вашей версии FILE * фактически является локальной переменной (как параметром) функции.Изменение его в функции не меняет его во внешнем мире.

При разработке функций, которые возвращают указатели (или что-либо еще в этом отношении), всегда предпочитайте возвращать указатель с помощью оператора return, а не пытатьсясделать это через список параметров.

...