Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > RTTI в MFC


Автор: deniska 6.4.2011, 12:15
Добрый день. В процессе работы наткнулся вот на какие грабли:
Код

void CSomeDlg::OnBnClickedSomeBtn()
{
    if( strcmp( typeid( this).name(), "class CSomeDlg" ) == 0 )
    {
        ;//do something
    }
}

такой код вызывает утечку памяти. Долго не доходили руки пофиксить данную "фичу".
Тут стал разбираться и возник вот какой вопрос:
правильно ли я понял, что в чистом виде RTTI не используется в MFC, а для этого создан "прородитель" CObject для основных MFC классов. Если это так, то почему? Что в MFC классах такого особенного?

и еще: настройки проекта на UNICODE/MULTI-BYTE должны влиять на возвращаемые данные от typeid?

ЗЫ. код с вытаскиванием имени через 
Код

    GetRuntimeClass()->m_lpszClassName
 

утечек не вызывает.

Автор: RastaDja 6.4.2011, 13:07
Цитата(deniska @  6.4.2011,  12:15 Найти цитируемый пост)
if( typeid( this).name(), "class CSomeDlg" ) == 0 )


Что-то мне кажется ты чего-то не дописал (подсчитай скобки и напиши то, что пропустил)

Автор: deniska 6.4.2011, 13:13
спс, в первом топике поправил. Только не в этом то суть. сам вызов
Код

typeid( this).name()

приводит к утечке

Автор: RastaDja 6.4.2011, 13:25
здесь дело может быть в том, что typeid(this).name() возвращает char*, что требует выделение памяти.

Попробуйте так
Код

char* ch = typeid( this).name();
//...
delete ch;

Автор: deniska 6.4.2011, 13:43
Цитата

Попробуйте так

 smile  ну нее, сами такое пробуйте))) не по феншую это...

Цитата

The type_info::name member function returns a const char* to a null-terminated string representing the human-readable name of the type. The memory pointed to is cached and should never be directly deallocated.

Автор: RastaDja 6.4.2011, 14:11
вот у меня такой код
Код

int s = 0;
    while(s<10000){
    typeid(int).name();
    ++s;
}

не вызывает утечек. Может это зависит от версии VS (у меня 2010)

Добавлено через 11 минут и 56 секунд
https://connect.microsoft.com/VisualStudio/feedback/details/106937/memory-leaks-reported-by-debug-crt-inside-typeinfo-name

Автор: Earnest 6.4.2011, 15:05
Цитата(deniska @  6.4.2011,  13:15 Найти цитируемый пост)
правильно ли я понял, что в чистом виде RTTI не используется в MFC, а для этого создан "прородитель" CObject для основных MFC классов. Если это так, то почему? Что в MFC классах такого особенного?

Просто MFC сильно старше, чем введение RTTI в стандарт, вот и реализовали его сами... А нынче остается для совместимости. Кроме того, MCF-шная реализация поддерживает доп. фичи - RuntimeClass и DynCreate, чтоб во многих случаях удобно.
Можно смешивать, не вопрос. Мне кажется, что утечка у тебя по другой причине.

Кроме того, если уж имеешь MFC-класс, то тип лучше проверять по-другому: IsKindOf (RUNTIME_CLASS (CSomeDlg)) -> здесь сравниваться будут указатели, а не строки. 
А если хочешь независимо от MFC, то так: dynamic_cast <CSomeDlg*>(this) != 0

Кроме того, сама по себе проверка типа наводит на подозрения о неудачном дизайне.

Автор: deniska 6.4.2011, 15:52
Цитата

вот у меня такой код

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

Цитата

Можно смешивать, не вопрос. Мне кажется, что утечка у тебя по другой причине

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

насчет каст-операторов  -  согласен, можно и через них, не вопрос, просто понять хочу в чем реальная причина утечки. Если причина в моем коде - естессна надо устранять источник.

ну и
Цитата

Кроме того, сама по себе проверка типа наводит на подозрения о неудачном дизайне.

 smile , я об этом здесь же попозже спрошу, ОК?))

Автор: mes 6.4.2011, 16:04
Цитата(deniska @  6.4.2011,  14:52 Найти цитируемый пост)
 просто понять хочу в чем реальная причина утечки.

в приведенном выше коде нет, и не может быть... 

Автор: deniska 6.4.2011, 16:09
кстати, тут усомнился и попробовал код RastaDjaы, то есть RTTI на простых типах...
Цитата

Detected memory leaks!
Dumping objects ->
{89} normal block at 0x00CC7F58, 4 bytes long.
 Data: <int > 69 6E 74 00 
{88} normal block at 0x00CC7F10, 8 bytes long.
 Data: <X       > 58 7F CC 00 00 00 00 00 
Object dump complete.

это я int переменную проверил...  smile 


попробовал консольное приложение - там со стандарнтыми типами работает нормально.
В чем может быть проблема? Менеджер ресурсов ложно срабатывает? Тогда почему только у меня на 2-студиях (2005, 2008)?

Автор: deniska 7.4.2011, 14:26
Может у кого есть какие-то мысли по вышеописанному?

Автор: voov 13.4.2011, 19:05
Это проблема далеко не новая и хорошо известная разработчикам майкрософт. 

Реальной утечки вызов typeid() не дает. Однако, менеджер памяти ошибочно выводит сообщение об утечке. Ничего критического для программы в этом нет, но сообщение здорово мозолит глаза. Проблема известна несколько лет, но так и не была решена (по крайней мере до выхода 10й студии). Информация была где-то на сайте майкрософт.

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

Автор: deniska 15.4.2011, 10:06
voov,  вот спасибо, успокоил. Хотя код я тоже уже переделал, чтоб глаза не мозолил.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)