powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / помогите понять.. try catch
13 сообщений из 13, страница 1 из 1
помогите понять.. try catch
    #34710029
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
class MyExc
{
private:
	char			*_m_info;
public:
	void			PrintInfo()const				{ printf("%s", _m_info); }
	const char		*GetInfo()const					{ return _m_info; }

	MyExc(const char *info);
	~MyExc();
}; // class MyExc


MyExc::MyExc(const char *info)
{
	printf("\nIn  constructor..'%s'", info);

	if (!info)	
		throw( MyExc("second exception") );
	
	size_t	len = strlen(info) +  1 ;
	_m_info = new char[len];
	memmove(_m_info, info, len);
}// MyExc()

MyExc::~MyExc()
{
	printf("\nIn  destructor..'%s'", _m_info);
	delete _m_info;
}// MyExc()

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void main()
{
	try
	{
		printf("\nIn try..");
		throw(MyExc(NULL));
	}// try
	catch(MyExc me)
	{
		printf("\nIn catch..");
		me.PrintInfo();
	}// catch
}



In try..
In constructor..'(null)'
In constructor..'second exception'
In destructor..'second exception'
In catch..▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌Г
In destructor..'▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌Г'

если закоменчу удаление строки в конструкторе так:
Код: plaintext
1.
2.
3.
4.
5.
MyExc::~MyExc()
{
	printf("\nIn  destructor..'%s'", _m_info);
	//delete _m_info;
}

то:

In try..
In constructor..'(null)'
In constructor..'second exception'
In destructor..'second exception'
In catch..second exception
In destructor..'second exception'
In destructor..'second exception'


не пойуму толком что тут вообще происходит, почему вызываются деструкторы раньше времени, почему два конструктора и три деструктора??
почему перехватывается только одно исключение, но программа не вылетает?
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34710194
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Первый случай:

1. Производится исключение с созданием объекта в стеке блока try -> constructor
2. В процессе создания объекта вызывается новое исключение. Создание первого объекта не завершено, вызов деструктора производиться не будет. -> constructor
3. Копируется объект в область исключительных ситуаций.
4. Удаляется объект в стеке блока try, удаляя данные. -> destructor
5. Копируется объект в область catch.
6. Выводяться данные в области catch, причем в объекте они уже удалены, поэтому вывод UB
7. Удаляется объект в области catch. Вывод данных тот же.
8. Попытка удаление данных по указателю на удаленные данные. UB - по всей видимости Access Violeishin. На этом работа завершается фатально.

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

Почему 3 конструктора и 2 деструктора: первый объект, которому было передано NULL не был создан до конца, и поэтому для него не было вызвано деструктора.

Как передать данные при копировании:
1. ввести конструктор копирования, который будет копировать данные.
2. использовать тип данных который может сам копировать данные по своиму указателю, и сам удаляться. Например std::string

Как уменьшить количество объектов: получать объект исключения в блок catch по ссылке.
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34710343
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо, прояснилось, но

авторПочему 3 конструктора и 2 деструктора: первый объект, которому было передано NULL не был создан до конца, и поэтому для него не было вызвано деструктора.

наоборот 2 конструктора и 3 деструктора
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34710392
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik wrote:

> наоборот 2 конструктора и 3 деструктора
для одного из объектов мог быть вызван оператор присваивания.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34710441
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Значит получается так:

1. In constructor..'(null)' вызывается исключением из блока try throw(MyExc(NULL));
2. In constructor..'second exception' вызывается из своего же конструктора.
3. При покидании первого конструктора происходит вызов деструктора In destructor..'second exception'
4. Попадаю в блок catch: In catch..second exception
5. При выходе из блока catch - In destructor..'second exception'
6. Последний вызов деструктора почему-то происходит по завершении main()
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34710527
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для большей наглядности сделал так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
unsigned		g_cnt =  0 ;

class MyExc
{
private:
	char			*_m_info;
	
public:
	void			PrintInfo()const				{ printf("%s", _m_info); }
	const char		*GetInfo()const					{ return _m_info; }

	MyExc(const char *info);
	~MyExc();
}; // class MyExc


MyExc::MyExc(const char *info)
{
	printf("\nIn  constructor..'%s' (%u)", info, ++g_cnt);

	if ( 1  == g_cnt)	
		throw( MyExc("second exception") );
		//throw("second exception");
	
	size_t	len = strlen(info) +  1 ;
	_m_info = new char[len];
	memmove(_m_info, info, len);
}// MyExc()

MyExc::~MyExc()
{
	printf("\nIn  destructor..'%s' (%u)", _m_info, g_cnt);
	//delete _m_info;
}// MyExc(0

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void main()
{
#ifdef _DEBUG
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	try
	{
		printf("\nIn try..");
		throw(MyExc("first exception"));
	}// try
	catch(MyExc me)
	{
		printf("\nIn catch..");
		me.PrintInfo();
	}// catch

}

вывод результатов:

In try..
In constructor..'first exception' (1)
In constructor..'second exception' (2)
In destructor..'second exception' (2)
In catch..second exception
In destructor..'second exception' (2)
In destructor..'second exception' (2)


про конструкторы копирования я понял, но не мойму для какого объекта (или его копии) вызывается последний третий конструктор при завершении программы?
еще не понимаю куда девается first exception, его же никто не обрабатывает, но программа тем не менее не завершается аварийно.
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34710796
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и еще

авторКак уменьшить количество объектов: получать объект исключения в блок catch по ссылке.

сделал так (правильно, нет - не знаю):

throw( &MyExc("second exception") );
...
catch(MyExc *me)

результат:
In try..
In constructor..'first exception' (1)
In constructor..'second exception' (2)
In destructor..'second exception' (2)
In catch..▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌

т.е. деструктор все для второго исключения вызывается в при выходе из первого конструктора и очищает строку

сделал так:
throw( MyExc("second exception") );
...
catch(MyExc &me)

результат:
In try..
In constructor..'first exception' (1)
In constructor..'second exception' (2)
In destructor..'second exception' (2)
In catch..▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌}
In destructor..'▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌}'


теперь появляется в еще какой-то деструктор.

1-ый деструктор вызывается при выходе из конструктора вызвавшего второе исключение
2-ой при выходе из блока catch (зачем он тут вызывается?)
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34711913
Ми
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вы на релизовской версии экспериментируете?
дебажная при раскомментированном delete ошибку дает - там повторное удаление.
Точнее будет во всех этих конструкторах-деструкторах breakpoint'ов повключать и отладчиком пройтись
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34711941
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиА вы на релизовской версии экспериментируете?
дебажная при раскомментированном delete ошибку дает - там повторное удаление.
Точнее будет во всех этих конструкторах-деструкторах breakpoint'ов повключать и отладчиком пройтись

про повторное удаление знаю, просто менять лень было, мне инетесно откуда еще один деструтор берется, когда по ссылке передаю
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34712022
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik2-ой при выходе из блока catch (зачем он тут вызывается?)

Потому что передаешь объект по значению. Он копируется в стек. Предавай по ссылке.

Звиняй, но если опять разгребать конструкторы и деструкторы по новой, можно мозг сломать. Тебе оно надо? Важно помнить следующее: При вызове исключения создается объект в стеке, где он вызывается. Далее он копируется копирующим конструктором (вроде как именно им) в область исключений. Это уже второй объект. Далее разворачивается стек до тех пор, пока исключение не будет перехвачено. В течении этого времени будет убит первый объект. Далее ты перехватываешь исключение. Ты его перехватываешь по значению, следовательно он тебе еще раз копируется (опять же оператором копирования). Ты получешь третий объект. Далее ты выходишь из catch. У тебя убивается 3-й объект. Далее обработка исключения завершена, т.к. ты не вызываешь throw без пераметров. Убивается второй объект. (ну, на счет очередности убийства 2-го и 3-го я мог перепутать).

Что мы имеем: Имеем объект носящий информацию о исключении. Имеем его данные. Имеем необходимость эти данные копировать из одного объекта в другой.
Что его из этого у нас нет? У нас не копируются данные. Вернее копируются, но конструктором копирования по умолчанию. Какой он? А вот такой:
Код: plaintext
1.
2.
MyExc::MyExc(MyExc &exc_) :
_m_info(exc_._m_info) {};
Конструктор копирования объекта вызывает конструктор копирования для каждого свойства класса. Какой конструктор копирования у указателя? Правильно, копирование самого указателя. Поэтому не стоит удивляться, что одни данные разделяются несколькими объектами и потом каждый пытается их очистить. Поэтому надо, чтобы у свойства был нужный конструктор копирования, например использоваить std::string или определить свой конструктор копирования объекта, указав в нем выделение памяти для нового свойства и скопировать данные.
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34712066
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я уже не удивляюсь, что он уничтожает строку, я ж написал, что все понял про конструктор копирования, я не понял почему при такой передаче, которую я понимаю, как передаче по ссылке:

сделал так:
Код: plaintext
1.
2.
throw( MyExc("second exception") );
...
catch(MyExc &me)

происхоит вызов еще второго деструктора, а при передаче по указателю, которые я сдалал так:
Код: plaintext
1.
2.
throw( &MyExc("second exception") );
...
catch(MyExc *me)

только один деструктор, откуда в первом случае берется второй не понимаю,т.к. предполагаю, что передача по ссылке и указателю в принципе равносильна
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34712839
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrikя уже не удивляюсь, что он уничтожает строку, я ж написал, что все понял про конструктор копирования, я не понял почему при такой передаче, которую я понимаю, как передаче по ссылке:

сделал так:
Код: plaintext
1.
2.
throw( MyExc("second exception") );
...
catch(MyExc &me)

происхоит вызов еще второго деструктора, а при передаче по указателю, которые я сдалал так:
Код: plaintext
1.
2.
throw( &MyExc("second exception") );
...
catch(MyExc *me)

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

Надо различать передачу объекта и получения. Во втором случае, ты передаешь ссылку на объект, который сразу же и убьется. Компилятор должен тебе ответить варнингом. Передавать ссылку можно только в том случае, когда ты уверен, что объект не убьется пока не будет обработан catch.

Да, по ссылке и указателю получение в данном случае равносильно, но здесь имеет значение предача исключению объекта. Во втором случае она по ссылке, значит тут объект не копируется в область исключений, следовательно получаем на объект меньше, следовательно нет одного деструктора.
...
Рейтинг: 0 / 0
помогите понять.. try catch
    #34712969
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в принципе, чтоб не парить моск ни себе, ни окружающим, добавляем в класс MyExc копирующий конструктор и оператор присваивания, наполняем их трассировочными выводами на экран и видим полную картину происходящего )))
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / помогите понять.. try catch
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]