Весь день бьюсь над ошибкой. Ничего не понимаю.
(VC6sp5. STL от Dinkumware, все пропатчено. Опции компилятора одинаковые. Debug Multithreaded DLL).
Две dll-ки.
В первой:
struct LABELCHECKBASE_API LabelCheckPost
{
LABELCHECK_SEVERITY severity; // enum
cwstring message; // аналог std::wstring
cwstring details;
LabelCheckPost()
: severity(LCS_INFO)
{
ATLTRACE("LCP::LCP(), %d\n", severity);
}
LabelCheckPost(LABELCHECK_SEVERITY sev, LPCWSTR msg, LPCWSTR dtl)
: severity(sev)
, message(msg)
, details(dtl)
{
ATLTRACE("LCP::LCP(%d...)\n", severity);
}
};
int LABELCHECKBASE_API compare(const LabelCheckPost& a, const LabelCheckPost& b);
inline bool operator < (const LabelCheckPost& a, const LabelCheckPost& b)
{
return compare(a, b) < 0;
}
typedef std::set<LabelCheckPost> set_of_labelcheck;
class LABELCHECKBASE_API CLabelCheckMailboxBase
: public ILabelCheckMailbox
{
public:
set_of_labelcheck m_set;
CLabelCheckMailboxBase();
virtual ~CLabelCheckMailboxBase();
// ILabelCheckMailbox
STDMETHODIMP report(LABELCHECK_SEVERITY sev, LPCWSTR wsMessage, LPCWSTR wsDetails);
// добавляет элемент в множество
};
class LABELCHECKBASE_API CLabelCheckMailbox
: public DummyUnknown<CLabelCheckMailboxBase>
{
};
Во второй — его использование:
CLabelCheckMailbox lcm;
/*1A*/
set_of_labelcheck& lcm_m_set = lcm.m_set;
/*1B*/
set_of_labelcheck lcm_m_set;
/*2A*/
lcm.report(LCS_INFO, cwstring("Label Check Rulez!!!"), cwstring("Just debug."));
/*2B*/
lcm_m_set.insert(LabelCheckPost
(LCS_INFO, cwstring("Label Check Rulez!!!"), cwstring("Just debug."))
);
if(lcm_m_set.empty())
return true;
set_of_labelcheck::const_iterator it = lcm_m_set.begin();
set_of_labelcheck::const_iterator end = lcm_m_set.end();
for(; it != end; ++it) /*3*/
{
LabelCheckPost const& post = *it;
. . .
}
И вот какая задница: если я в (*1*) напишу вариант A, (и, соответственно, (*2A*)), то все работает. Заходим в цикл один раз, там действительно то, что мы хотели.
Если же (*1A*) & (*2B*) — то, несмотря на то, что lcm_m_set._Tr->_Size == 1, окажется, что it==end. В цикл не попадем.
Странно... Но и это еще не все! Если мы напишем (*1A*)+(*2A*), то попадем в цикл более одного раза (и, естественно, получим ошибку защиты памяти).
Интересно, что в обоих последних случаях наблюдается еще одна странность: выполняется compare() между свежевставляемым объектом и неинициализированной памятью из корневого фальш-узла дерева!!!
Я уже все перепробовал: и включал-выключал inline методов как LabelCheckPost, так и CLabelCheckMailboxBase, и делал им виртуальные деструкторы, и всякие под-объекты добавлял. Никакой разницы.
(=^.^=) Neko ... << RSDN@Home 1.0 beta 6a >>
Ведь знал же, что динкумверская реализация дерева имеет статические члены.
В общем, буду заниматься редизайном
(=^.^=) Neko ... << RSDN@Home 1.0 beta 6a >>
Здравствуйте, ilnar, Вы писали:
I>между модулями все геморойно. я обычно в этом случае оставляю интерфейс в виде h файлов для одного модуля и реализацию в другом. Все действия — создание объекта, уничтожение, работа с ними делегирую модулю, к которой (и только к ней ) подключил сср файл
В общем, загнал std::set в приватные члены, сделал произвольный доступ по индексу (а, пофиг скорость). Всю работу с ним — в cpp.
Хотя по-человечески надо было б разнести интерфейс и реализацию.
(=^.^=) Neko ... << RSDN@Home 1.0 beta 6a >>