LINUX.ORG.RU

Снова исключения


0

0

Короче обрисовываю проблему подробно:
Есть класс Bolvan:
[code]

class Bolvan {
private:
	char* device;
	/*И т.д.*/

protected:
	int sg_fd;
public:
	struct FDError {
		 char* message;
		FDError (char* p)  { message = p; }
		};
	Bolvan (const char* io_device);
/*и т.д.*/

};

[/code]

У этого класса Bolvan усть конструктор:
[code]

Bolvan::Bolvan (const char* io_device)
{
	sg_fd = open (io_device, O_RDONLY);
	if (sg_fd < 0) {
		char *msg;
		sprintf (msg, "Unable to open device %s\n", io_device);
#ifdef DEBUG
		sprintf (msg, "open (io_device, O_RDONLY) failed. \n Maybe device name is not valid.\n Check open() call in bolvan.cpp\n");
#endif
		throw Bolvan::FDError (msg);
  }

/*И т.д.*/
};

[/code]

В драйвере программы:
[code]

Bolvan *CB;
try {
	CB = new Bolvan ("/dev/hdc");
}
catch (Bolvan::FDError) {
   delete CB;
};

[/code]

Проблема: После обработки исключения возникает Segmentation fault. причем даже если я сделаю просто
[code]

catch (...) {

}

[/code]

То все равно возникает SF. В чем фигня? Причем все, что внутри catch выполняется (проверял дебаггером), а затем возникает SF.  Самая проблема, что на одном форуме один челове выложил пример с исключением, котолрый у него РАБОТАЛ. Я этот пример компилю, у меня не работает. Может g++ обновить? У меня g++ 3.2
Помогите пожалуйста.


anonymous

> delete CB;

Не понял. Как это ты удаляешь несозданный объект?

anonymous
()
Ответ на: комментарий от PETER

Тогда уж и "Bolvan *CB;" на "Bolval *CB = 0;"

anonymous
()
Ответ на: комментарий от PETER

> Замени "delete CB" на "if ( CD ) delete CB"

дык стандарт долбоебских плюсов вроде говорит что delete( 0 ) корректное действие.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

Обьект создается. Просто он пустой

anonymous
()

так а что ты хотел кроме СФ??

У тебя в CB изначально мусор. Когда исключение выброшено из конструктора то присваивания CB нового указателя не происходит. Ты получаешь СФ. Проинициализируй CB нулем и все..

dilmah ★★★★★
()

Епыть, ребеночка то и не заметили! Когда формируешь сообщение об ошибке (sprintf) - не плохо бы и буфер подготовить ;)

PETER ★★
()

Дык при обработке исключения объект уже мертв.

Ты ж кидаешь exception из конструктора.

anonymous
()
Ответ на: комментарий от anonymous

И еще.

Segfault за то, что CB не инициализирована. До присваивания проц. не дошел. Можеш проверить в GDB.

А еще можеш включить warnings по максимуму и -O2. Скорей всего gcc даст на это warning.

anonymous
()

Очень плохо написано. Когда возникает исключит. ситуация 1. нужно конечно выделеть память под сообщение 2. эту память нужно удалить - между прочим. 3. нужен деструктор, в котором удаляется память из буфера char * device; или проверяется на NULL, а затем удаляется. 4. Правила хорошего тона при программировании гласят, что всем указателям должны быть присвоены значения NULL при инициализации => в конструкторе: device = NULL; и еще рекомендую прочитать книжку А.Голуб правила программирования на С/С++

короче в классе:

char * m_p_chDevice;

префикс - указывает что переменная класса, указатель на символьный тип. Венгерская натация. Отсюда рекомендую: 1. создай класс "clError" - один на всю программу в котором будет выделяться память в конструкторе под сообщение а затем в деструкторе удаляться; 2. Когда исключит. ситуация то просто { char msg[1024]; memset(msg,'\0',sizeof(msg)); sprintf (msg, "Unable to open device %s\n", io_device); throw clError(msg); }

.... } // try catch(clError & er) { printf("%s \n", er()); }

3. Ну конечно в классе "clError" все правильно сделать конструктор копирования, оператор присваивания, конструктор инициализации;

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.