string, map, _bstr_t и утечки памяти
От: Всеволод Россия  
Дата: 26.11.03 09:20
Оценка:
Всем привет !

Не могу понять, в чем дело. Есть следующий код
   // имеем map
   map <string, string> m_mapKey2Category;

   ...
  
   // получаем две строки в виде _bstr_t
   _bstr_t sCategory=GetKey(pCategory);
   _bstr_t bsKey=ItemName(atr);

   // засовываем их в map
   m_mapKey2Category[string(bsKey)]=string(sCategory);

   ...

   // потом освобождаем
   m_mapKey2Category.clear();


При завершении программы появляются утечки памяти следующего содержания

Detected memory leaks!
Dumping objects ->
{2419} normal block at 0x06EBD318, 48 bytes long.
Data: <f33a788d-d9f3-42> 66 33 33 61 37 38 38 64 2D 64 39 66 33 2D 34 32
{2418} normal block at 0x06EBD290, 72 bytes long.
Data: < r 8M r > D8 72 01 01 38 4D EB 06 D8 72 01 01 CD CD CD CD
{2413} normal block at 0x06EBD220, 48 bytes long.
Data: <de7c1087-6b38-4c> 64 65 37 63 31 30 38 37 2D 36 62 33 38 2D 34 63
{2412} normal block at 0x06EBD198, 72 bytes long.
Data: < r p r > D8 72 01 01 70 96 EB 06 D8 72 01 01 CD CD CD CD

И так далее...


Судя по содержанию — это строки из map.

Если написать
   m_mapKey2Category[string("123")]=string("Bla-bla-bla");

утечки чудесным образом изчезают.

Коллеги, подскажите, где я неправ ! На кого грешить, на string или на _bstr_t ? Или на map ? (Хотя он тут явно не причем)
Re: string, map, _bstr_t и утечки памяти
От: Bell Россия  
Дата: 26.11.03 09:30
Оценка:
Здравствуйте, Всеволод, Вы писали:

Покажи реализацию GetKey и ItemName
Любите книгу — источник знаний (с) М.Горький
Re: string, map, _bstr_t и утечки памяти
От: SergTr Россия www.mountain.ru
Дата: 26.11.03 09:31
Оценка:
Здравствуйте, Всеволод, Вы писали:

В> // получаем две строки в виде _bstr_t

В> _bstr_t sCategory=GetKey(pCategory);
В> _bstr_t bsKey=ItemName(atr);

При получении строки типа BSTR при вызове Winapi происходит выделение памяти системой.
После использования этих строк (в данном случае после получения объектов string) эту память стоит освободить:
SysFreeString
Re: string, map, _bstr_t и утечки памяти
От: sercher Украина  
Дата: 26.11.03 09:31
Оценка:

//Update static text with new value
BSTR tmpBStr;

m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr(tmpBStr, FALSE); //necessary to avoid a memory leak

SetDlgItemText(IDC_CURPROPVAL, tmpbstr);

Note The conversion issue does not apply in a Unicode build. However, conversion is needed in a Win32 build.

In addition to the casting issue, there is also a memory issue. If the following code sample had been used, instead of the preceding code, a memory leak would have resulted:

//Update static text with new value
BSTR tmpBStr;

m_pObject1->get_ObjectString(&tmpBStr);
_bstr_t tmpbstr;

tmpbstr= tmpBStr; //Caution: Memory leak occurs
SetDlgItemText(IDC_CURPROPVAL, tmpbstr);

Re[2]: string, map, _bstr_t и утечки памяти
От: sercher Украина  
Дата: 26.11.03 09:33
Оценка:

The leak occurs when the tmpbstr variable is initialized. A call to SysAllocString (reference available in the Component Services section of the Platform SDK) is automatically made when creating the tmpbstr variable. This new allocation is never freed later, resulting in a memory leak. Using this version of the _bstr_t constructor avoids the issue by attaching the BSTR object to tmpbstr without a call to SysAllocString. For more information on this issue, see _bstr_t::_bstr_t (reference available in the C++ Language Reference section of the Visual C++ Documentation).

Re[2]: string, map, _bstr_t и утечки памяти
От: Всеволод Россия  
Дата: 26.11.03 09:35
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Всеволод, Вы писали:


B>Покажи реализацию GetKey и ItemName


А вот это не мое. Но они работают корректно, в них утечек нет.
Приведу пример более подробно
for (...)
{
   _bstr_t sCategory=GetKey(pCategory);
   _bstr_t bsKey=ItemName(atr);

   m_mapKey2Category[string(bsKey)]=string(sCategory); // Вот так утечки будут

   m_mapKey2Category[string("123")]=string("Bla-bla-bla"); // А вот так нет
}
Re[2]: string, map, _bstr_t и утечки памяти
От: Всеволод Россия  
Дата: 26.11.03 09:40
Оценка:
Здравствуйте, SergTr, Вы писали:

ST>Здравствуйте, Всеволод, Вы писали:


В>> // получаем две строки в виде _bstr_t

В>> _bstr_t sCategory=GetKey(pCategory);
В>> _bstr_t bsKey=ItemName(atr);

ST>При получении строки типа BSTR при вызове Winapi происходит выделение памяти системой.

ST>После использования этих строк (в данном случае после получения объектов string) эту память стоит освободить:
ST>SysFreeString

Мне все же кажется что дело в создании string из _bstr_t
for (...)
{
   _bstr_t sCategory=GetKey(pCategory);
   _bstr_t bsKey=ItemName(atr);

   m_mapKey2Category[ string(bsKey) ]=string(sCategory); // Вот так утечки будут

   m_mapKey2Category[string("123")]=string("Bla-bla-bla"); // А вот так нет
}

Во втором случае _bstr_t тоже получаются, но не преобразуются в string
Re[3]: string, map, _bstr_t и утечки памяти
От: Bell Россия  
Дата: 26.11.03 09:50
Оценка:
Здравствуйте, Всеволод, Вы писали:

B>Покажи реализацию GetKey и ItemName

В>А вот это не мое. Но они работают корректно, в них утечек нет.

И все-таки. Или это очень сложно?
Любите книгу — источник знаний (с) М.Горький
Re[2]: string, map, _bstr_t и утечки памяти
От: Всеволод Россия  
Дата: 26.11.03 09:50
Оценка:
Здравствуйте, SergTr, Вы писали:

ST>Здравствуйте, Всеволод, Вы писали:


В>> // получаем две строки в виде _bstr_t

В>> _bstr_t sCategory=GetKey(pCategory);
В>> _bstr_t bsKey=ItemName(atr);

ST>При получении строки типа BSTR при вызове Winapi происходит выделение памяти системой.

ST>После использования этих строк (в данном случае после получения объектов string) эту память стоит освободить:
ST>SysFreeString

Попробовал вот так
for (...)
{
   _bstr_t sCategory=GetKey(pCategory);
   _bstr_t bsKey=ItemName(atr);

   m_mapKey2Category[string(bsKey)]=string(sCategory);

   SysFreeString(sCategory);
   SysFreeString(bsKey);
}

Эффект тот же — утечки.

На всякий случай — GetKey и ItemName возвращают _variant_t
Re[3]: Блин, ошибся
От: SergTr Россия www.mountain.ru
Дата: 26.11.03 09:58
Оценка:
Здравствуйте, Всеволод, Вы писали:

Читаю _bstr_t,а думаю об обычном BSTR
Re[4]: string, map, _bstr_t и утечки памяти
От: Всеволод Россия  
Дата: 26.11.03 09:59
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Всеволод, Вы писали:


B>>Покажи реализацию GetKey и ItemName

В>>А вот это не мое. Но они работают корректно, в них утечек нет.

B>И все-таки. Или это очень сложно?


Попробую
inline _variant_t GetKey ( IAttributesPtr a )
{
  _variant_t key;
  a->get_Key ( &key );
  return key;
}

inline _variant_t ItemName ( IAttributeItemPtr a )
{
  _variant_t key;
  a->get_Key ( &key );
  return key;
}
Re[3]: string, map, _bstr_t и утечки памяти
От: folk Россия  
Дата: 26.11.03 12:22
Оценка:
Здравствуйте, Всеволод, Вы писали:

В>Мне все же кажется что дело в создании string из _bstr_t

В>
В>for (...)
В>{
В>   _bstr_t sCategory=GetKey(pCategory);
В>   _bstr_t bsKey=ItemName(atr);

В>   m_mapKey2Category[ string(bsKey) ]=string(sCategory); // Вот так утечки будут

В>   m_mapKey2Category[string("123")]=string("Bla-bla-bla"); // А вот так нет
В>}
В>

В>Во втором случае _bstr_t тоже получаются, но не преобразуются в string

А если попробовать вызвать _bstr_t::operator const char*() без всяких string и map, лики остаются? Например так:

volatile const char* str1 = bsKey;
volatile const char* str2 = sCategory;


Если мне не изменяет память, то при вызове оператора const char*() будет выделена память под char-представление _bstr_t. Может у тебя чего не так срабатывает и деструктор не удаляет этот буфер?
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re: string, map, _bstr_t и утечки памяти
От: Tester1  
Дата: 20.06.05 11:41
Оценка:
Здравствуйте, Всеволод, Вы писали:

В>При завершении программы появляются утечки памяти следующего содержания

В>[q]
В>Detected memory leaks!
В>Dumping objects ->
В>{2419} normal block at 0x06EBD318, 48 bytes long.
В> Data: <f33a788d-d9f3-42> 66 33 33 61 37 38 38 64 2D 64 39 66 33 2D 34 32
В>{2418} normal block at 0x06EBD290, 72 bytes long.
В> Data: < r 8M r > D8 72 01 01 38 4D EB 06 D8 72 01 01 CD CD CD CD
В>{2413} normal block at 0x06EBD220, 48 bytes long.
В> Data: <de7c1087-6b38-4c> 64 65 37 63 31 30 38 37 2D 36 62 33 38 2D 34 63
В>{2412} normal block at 0x06EBD198, 72 bytes long.
В> Data: < r p r > D8 72 01 01 70 96 EB 06 D8 72 01 01 CD CD CD CD

Сам столкнулся с такой пробемой. Ошибка была в том, что класс, члены которого
инициировались этими пресловутыми BSTR-ами являся COM классом EXE сервера.
Клиент, который создавал СОМ объект, "забывал" его особождать. И когда закрывался
ЕХЕ сервер, не вызывались деструкторы класса и как следствие "вылезали" mermory leeks.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.