std::set между двумя модулями. HELP!
От: Кодт Россия  
Дата: 08.05.03 13:24
Оценка:
Весь день бьюсь над ошибкой. Ничего не понимаю.

(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 >>
Перекуём баги на фичи!
Re: Сам дурак, наверное.
От: Кодт Россия  
Дата: 08.05.03 13:47
Оценка:
Ведь знал же, что динкумверская реализация дерева имеет статические члены.

В общем, буду заниматься редизайном
(=^.^=) Neko ... << RSDN@Home 1.0 beta 6a >>
Перекуём баги на фичи!
Re: std::set между двумя модулями. HELP!
От: ilnar Россия  
Дата: 10.05.03 13:17
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Весь день бьюсь над ошибкой. Ничего не понимаю.


К>(VC6sp5. STL от Dinkumware, все пропатчено. Опции компилятора одинаковые. Debug Multithreaded DLL).


между модулями все геморойно. я обычно в этом случае оставляю интерфейс в виде h файлов для одного модуля и реализацию в другом. Все действия — создание объекта, уничтожение, работа с ними делегирую модулю, к которой (и только к ней ) подключил сср файл
Re[2]: std::set между двумя модулями. HELP!
От: Кодт Россия  
Дата: 12.05.03 08:04
Оценка:
Здравствуйте, ilnar, Вы писали:

I>между модулями все геморойно. я обычно в этом случае оставляю интерфейс в виде h файлов для одного модуля и реализацию в другом. Все действия — создание объекта, уничтожение, работа с ними делегирую модулю, к которой (и только к ней ) подключил сср файл


В общем, загнал std::set в приватные члены, сделал произвольный доступ по индексу (а, пофиг скорость). Всю работу с ним — в cpp.
Хотя по-человечески надо было б разнести интерфейс и реализацию.
(=^.^=) Neko ... << RSDN@Home 1.0 beta 6a >>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.