При этом, если запускать это в основном потоке, утечки не наблюдается.
Очевидно так же, что к моменту выхода из main, второй поток уже завершился.
Как с этим жить ?
Здравствуйте, stil.man, Вы писали:
SM>При этом, если запускать это в основном потоке, утечки не наблюдается. SM>Очевидно так же, что к моменту выхода из main, второй поток уже завершился. SM>Как с этим жить ?
Допустим память выделяется динамически под запрос один раз в куче рантайма.
Это считается утечкой?
Дело в том, что в Visual C++ main вызывается из стартового (он же финишный) код. Убедиться в этом, а заодно и посмотреть на него проще простого — ставим брекпойнт на закрывающую фигурную скобку main, по достижении брекпойнта нажимает F11 и оказываемся там. Если дальше этот код протрассировать, то дойдем до ExitProcess. А ExitProcess убивает все потоки и заканчивает процесс. Память, выделенная при запуске потока стартовым кодом потока (а его посмотреть также несложно, протрассировав __beginthreadex) остается неосвобожденной, так как нормального окончания потока по прямому (явный вызов_endthreadex) или косвенному (вызов _endthreadex в финишном коде потока после выхода на закрывающую фигурную скобку потоковой функции) не произошло.
Вот и все.
Здравствуйте, Caracrist, Вы писали:
C>Здравствуйте, stil.man, Вы писали:
SM>>При этом, если запускать это в основном потоке, утечки не наблюдается. SM>>Очевидно так же, что к моменту выхода из main, второй поток уже завершился. SM>>Как с этим жить ?
C>Допустим память выделяется динамически под запрос один раз в куче рантайма. C>Это считается утечкой?
Получается что с точки зрения из собственного рантайма считается. Это он мне показывает что это утечки.
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, stil.man, Вы писали:
SM>>Очевидно так же, что к моменту выхода из main, второй поток уже завершился. SM>>Как с этим жить ?
U>моя личная рекомендация: программа всегда должна дожидаться своих порожденных потоков, вызовите join
Ваша личная очевидная рекомендация кэп, никак не решает описанную проблему.
Здравствуйте, stil.man, Вы писали:
SM>Те же самые утечки.
предположу, что утечки связаны не с механизмом запуска потоков, а с содержимым функции f
1) уберите доп. потоки, вызовите функцию f из main, проверьте утечки
2) уберите вызов typeid из f, выполните ее в другом потоке, проверьте утечки
если утечки в пункте 1) остались, то снова предположу, что связано это с вызовом typeid, ведь данная функция должна возвращать ссылку на typeinfo. время жизни этого объекта должно переживать приложение (в стандарте более точно описано как долго должна жить ссылка)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, stil.man, Вы писали:
PD>Дело в том, что в Visual C++ main вызывается из стартового (он же финишный) код. Убедиться в этом, а заодно и посмотреть на него проще простого — ставим брекпойнт на закрывающую фигурную скобку main, по достижении брекпойнта нажимает F11 и оказываемся там. Если дальше этот код протрассировать, то дойдем до ExitProcess. А ExitProcess убивает все потоки и заканчивает процесс. Память, выделенная при запуске потока стартовым кодом потока (а его посмотреть также несложно, протрассировав __beginthreadex) остается неосвобожденной, так как нормального окончания потока по прямому (явный вызов_endthreadex) или косвенному (вызов _endthreadex в финишном коде потока после выхода на закрывающую фигурную скобку потоковой функции) не произошло. PD>Вот и все.
Если по трассировать как происходит выход из второго потока, то вот тут (Microsoft Visual Studio 10.0\VC\crt\src\threadex.c: line 312) происходит вызов _endthreadex: --> _endthreadex (
( (unsigned (__CLR_OR_STD_CALL *)(void *))(((_ptiddata)ptd)->_initaddr) )
( ((_ptiddata)ptd)->_initarg ) ) ;
Собственно мне непонятно каким может быть ещё более нормальный выход из потока ?
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, stil.man, Вы писали:
SM>>Те же самые утечки.
U>предположу, что утечки связаны не с механизмом запуска потоков, а с содержимым функции f U>1) уберите доп. потоки, вызовите функцию f из main, проверьте утечки U>2) уберите вызов typeid из f, выполните ее в другом потоке, проверьте утечки U>если утечки в пункте 1) остались, то снова предположу, что связано это с вызовом typeid, ведь данная функция должна возвращать ссылку на typeinfo. время жизни этого объекта должно переживать приложение (в стандарте более точно описано как долго должна жить ссылка)
Вы невнимательно прочли первый пост, в нем ясно говорится что если ту же функцию вызвать из основного потока то утечки нет.
Кроме вывода typeid.name() в функции нет ничего, так что убирать там нечего. Так же очевидно, что содержимое утечки (<struct vvv1 >) явно указывает на то что утекла именно name()
время жизни этого объекта должно переживать приложение
С этим утверждением сложно согласится Хотя, возможно, некоторые приложения верят в жизнь после смерти
SM>Если по трассировать как происходит выход из второго потока, то вот тут (Microsoft Visual Studio 10.0\VC\crt\src\threadex.c: line 312) происходит вызов _endthreadex: -->> _endthreadex ( SM> ( (unsigned (__CLR_OR_STD_CALL *)(void *))(((_ptiddata)ptd)->_initaddr) ) SM> ( ((_ptiddata)ptd)->_initarg ) ) ;
SM>Собственно мне непонятно каким может быть ещё более нормальный выход из потока ?
main запускает второй поток, после чего main завершается и происходит выход в код, вызвавший main, а он вызывает ExitProcess, который убивает все потоки. Код выше не исполняется, так как поток помер.
Здравствуйте, stil.man, Вы писали:
SM>Вы невнимательно прочли первый пост, в нем ясно говорится что если ту же функцию вызвать из основного потока то утечки нет.
действительно, невнимательно
SM>Кроме вывода typeid.name() в функции нет ничего, так что убирать там нечего. Так же очевидно, что содержимое утечки (<struct vvv1 >) явно указывает на то что утекла именно name()
собственно я предложил убрать вызовы typeid
SM>
время жизни этого объекта должно переживать приложение
SM>С этим утверждением сложно согласится Хотя, возможно, некоторые приложения верят в жизнь после смерти