Использование условных файловых дескрипторов в C ++ - PullRequest
0 голосов
/ 21 апреля 2011

Я работаю с библиотекой C ++, которая широко использует такие конструкции, как:

FILE *out_file1, *out_file2 ... *out_fileN;

//for some output files, but not all:
out_file1 = fopen( filename, "w" )

//later
if( out_file1 ) fprintf( ... )
if( out_file2 ) fprintf( ... )

Кажется, что это работает нормально под g ++ на OS X. Однако, когда я запускаю ее на linux, я получаю. ошибка сегментацияПроверяя код, out_file часто инициализируется ненулевыми значениями.

Я пытался добавить

out_file = NULL

, но это, похоже, не помогает - на самом деле, согласно отладчику, это не меняет значение out_file.

Может ли кто-нибудь помочь в следующем:

Является ли это признанным и разумным способом выполнения файлового ввода-вывода (т.е. с помощью файловых указателей в условных выражениях)

Почему значение указателя не установлено на ноль?

Как мне установить его на ноль?

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

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

class IO
{
private:
    FILE* opFile

    IO()
    {
         //At this point, opFile == 0x40
         opFile = NULL; //At this point opFile is still 0x40
    }
}

Так что, очевидно, если он выходит из конструктора сненулевое значение, что-нибудь вроде:

if( opFile ) fprintf( ... )

потерпит неудачу.Но как удается выйти из конструктора с ненулевым значением?

И в случае, если это помогает, это работает "как положено" в gcc на OSX, но не на g ++ - 4.3 или g ++4.4 в Ubuntu.

Ответы [ 5 ]

2 голосов
/ 21 апреля 2011

Ваша проблема в другом месте кода, скорее всего в * printf, которые вы упоминаете?

Покажите нам больше кода или воспользуйтесь отладчиком, чтобы найти, где он падает.

g++ -O0 -Wall -g mysource.cpp -o test
gdb ./test
(gdb) run argument1 argument2

Кроме того, посмотрите на valgrind для дополнительных инструментов проверки памяти

valgrind ./test

$ 0,02

Обновление

Добавлено -O0, чтобы избежать путаницы в анализе с результатами правильной оптимизации компилятора:)

1 голос
/ 21 апреля 2011

Это реальный код из вашей программы?

FILE* out_file1, out_file2 ... out_fileN

Тогда только out_file1 - это FILE*, а все остальные - просто FILE. Это объяснило бы их «забавные ценности».

1 голос
/ 21 апреля 2011

in C ++ , вы должны использовать iostreams, поможет вам избежать всех этих проблем ...

std::ifstream in ("some_file");

if (in)
{
  // do stuff with stream...
}
0 голосов
/ 21 апреля 2011

Возможно, компилятор оптимизирует ваш код.Присвоение out_file NULL за мгновение до того, как оно будет присвоено возвращаемым значением fopen, не имеет смысла.Компилятор может знать это и не беспокоиться о назначении NULL.

Вы можете определить и инициализировать значение в одной строке:

FILE* out_file = fopen( filename, "w" )

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

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

0 голосов
/ 21 апреля 2011

В C ++ вы должны использовать std::fstream (или std::istream / std::ostream) для файлового ввода-вывода, если у вас нет веских причин не делать этого.Тогда, скорее всего, у вас не будет этой проблемы, так как вы можете просто написать это:

std::ifstream file("myfile.txt");

while(file) { // this checks for any error
    // do stuff with file
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...