Траблы с CArray
От: beldmit  
Дата: 19.12.02 09:12
Оценка:
Есть класс CVisit

Есть тип CVisitArray — CArray<CVisit, CVisit&>

Есть класс CPatient, один из элементов которого — CVisitArray.

Есть тип CPatientArray — CArray<CPatient, CPatient&>

Один из элементов документа имеет тип CPatientArray. Несколько
переменных-членов CVisit и CPatient имеют тип CString и COLEDateTime,
остальные — фиксированного размера, указателей нет, поэтому деструкторы
пустые.

Указатель на документ передается в плагин(dll), который позволяет
добавлять/редактировать как пациентов, так и визиты. При добавлении визита
все нормально работает, пока не завершается работа приложения. После этого
случается Access Violation. Где копать, чтобы его победить?
Re: Траблы с CArray
От: kmn Украина  
Дата: 19.12.02 10:09
Оценка:
Здравствуйте, beldmit, Вы писали:

B>Есть класс CVisit

B>
B>Есть тип CVisitArray — CArray<CVisit, CVisit&>
B>
B>Есть класс CPatient, один из элементов которого — CVisitArray.
B>
B>Есть тип CPatientArray — CArray<CPatient, CPatient&>
B>
B>Один из элементов документа имеет тип CPatientArray. Несколько
B>переменных-членов CVisit и CPatient имеют тип CString и COLEDateTime,
B>остальные — фиксированного размера, указателей нет, поэтому деструкторы
B>пустые.
B>
B>Указатель на документ передается в плагин(dll), который позволяет
B>добавлять/редактировать как пациентов, так и визиты. При добавлении визита
B>все нормально работает, пока не завершается работа приложения. После этого
B>случается Access Violation. Где копать, чтобы его победить?


Проблема с наличием двух (или более) диспетчеров памяти.

в контексте одного диспетчера памяти (dll) объект создается,
а в контексте другог (exe) — грохается.
Re[2]: Траблы с CArray
От: beldmit  
Дата: 19.12.02 10:32
Оценка:
Здравствуйте, kmn, Вы писали:

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


B>>Есть класс CVisit

B>>
B>>Есть тип CVisitArray — CArray<CVisit, CVisit&>
B>>
B>>Есть класс CPatient, один из элементов которого — CVisitArray.
B>>
B>>Есть тип CPatientArray — CArray<CPatient, CPatient&>
B>>
B>>Один из элементов документа имеет тип CPatientArray. Несколько
B>>переменных-членов CVisit и CPatient имеют тип CString и COLEDateTime,
B>>остальные — фиксированного размера, указателей нет, поэтому деструкторы
B>>пустые.
B>>
B>>Указатель на документ передается в плагин(dll), который позволяет
B>>добавлять/редактировать как пациентов, так и визиты. При добавлении визита
B>>все нормально работает, пока не завершается работа приложения. После этого
B>>случается Access Violation. Где копать, чтобы его победить?

kmn>

kmn>Проблема с наличием двух (или более) диспетчеров памяти.

kmn>в контексте одного диспетчера памяти (dll) объект создается,

kmn>а в контексте другог (exe) — грохается.

Не очень понимаю. Чем это отличается от обычной передачи указателя в функцию dll для модификации? Я скорее поверю в какую-то ошибку в конструкторе CVisit, из-за чего в память пишется фигня. На этом форуме я нашел похожую проблему — тогда симптомы ошибки исчезали после убирания virtual из описания деструктора, а сама ошибка была следствием выхода где-то за пределы массива. Код живет дома, вечером проверю.

Если Вы правы, то что с этим предполагается делать? В принципе этот плагин я могу счесть частью основной функциональности и не совать в dll, но нет ли более правильного способа?
Re[3]: Траблы с CArray
От: kmn Украина  
Дата: 19.12.02 10:58
Оценка:
Здравствуйте, beldmit, Вы писали:


B>Не очень понимаю. Чем это отличается от обычной передачи указателя в функцию dll для модификации? Я скорее поверю в какую-то ошибку в конструкторе CVisit, из-за чего в память пишется фигня. На этом форуме я нашел похожую проблему — тогда симптомы ошибки исчезали после убирания virtual из описания деструктора, а сама ошибка была следствием выхода где-то за пределы массива. Код живет дома, вечером проверю.


B>Если Вы правы, то что с этим предполагается делать? В принципе этот плагин я могу счесть частью основной функциональности и не совать в dll, но нет ли более правильного способа?


не обращаться к массивам непосредственно

template <class TYPE, class ARG_TYPE = const TYPE&>
class CArrayV
{
public:
    virtual int Add(ARG_TYPE v)
       {
            array.Add(v)
       }
     
    virtual int RemoveAll()
       {
            m_array.RemoveAll();
       }


protected:
     CArray<TYPE, ARG_TYPE> m_array;
};


template <class TYPE, class ARG_TYPE = const TYPE&>
class CArrayEx
{
public:
    int Add(ARG_TYPE v)
       {
            array.Add(v)
       }
     
    int RemoveAll()
       {
            m_array.RemoveAll();
       }


protected:
     CArray<TYPE, ARG_TYPE> m_array;
};



// EXE

CArrayV <int, int> arrayV;
CArrayEx <int, int> arrayEx;

MyDllFunctionEX(&arrayEx);
MyDllFunctionV(&arrayV);


arrayEx.RemoveAll(); // Здесь будет бабах
arrayV.RemoveAll();  // OK

// DLL

void MyDllFunctionEX(CArrayEx<int, int> *array)
{
   array->Add(128);
   array->Add(256);
}

void MyDllFunctionV(CArrayEx<int, int> *array)
{
   array->Add(128);
   array->Add(256);
}
Re[4]: Траблы с CArray
От: beldmit  
Дата: 19.12.02 11:10
Оценка:
Здравствуйте, kmn, Вы писали:

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


B>>Если Вы правы, то что с этим предполагается делать? В принципе этот плагин я могу счесть частью основной функциональности и не совать в dll, но нет ли более правильного способа?


kmn>не обращаться к массивам непосредственно


kmn>
kmn>template <class TYPE, class ARG_TYPE = const TYPE&>
kmn>class CArrayV
kmn>{
kmn>public:
kmn>    virtual int Add(ARG_TYPE v)
kmn>       {
kmn>            array.Add(v)
kmn>       }
kmn>     
kmn>    virtual int RemoveAll()
kmn>       {
kmn>            m_array.RemoveAll();
kmn>       }

kmn>
kmn>protected:
kmn>     CArray<TYPE, ARG_TYPE> m_array;
kmn>};

kmn>
kmn>template <class TYPE, class ARG_TYPE = const TYPE&>
kmn>class CArrayEx
kmn>{
kmn>public:
kmn>    int Add(ARG_TYPE v)
kmn>       {
kmn>            array.Add(v)
kmn>       }
kmn>     
kmn>    int RemoveAll()
kmn>       {
kmn>            m_array.RemoveAll();
kmn>       }

kmn>
kmn>protected:
kmn>     CArray<TYPE, ARG_TYPE> m_array;
kmn>};
kmn>


kmn>

kmn>
kmn>// EXE

kmn>CArrayV <int, int> arrayV;
kmn>CArrayEx <int, int> arrayEx;

kmn>MyDllFunctionEX(&arrayEx);
kmn>MyDllFunctionV(&arrayV);

kmn>
kmn>arrayEx.RemoveAll(); // Здесь будет бабах
kmn>arrayV.RemoveAll();  // OK

kmn>// DLL

kmn>void MyDllFunctionEX(CArrayEx<int, int> *array)
kmn>{
kmn>   array->Add(128);
kmn>   array->Add(256);
kmn>}

kmn>void MyDllFunctionV(CArrayEx<int, int> *array)
kmn>{
kmn>   array->Add(128);
kmn>   array->Add(256);
kmn>}

kmn>



То есть определить виртуальные методы добавления элемента во внутренний массив и удаления всех элементов?
Re[5]: Траблы с CArray
От: kmn Украина  
Дата: 19.12.02 11:16
Оценка:
Здравствуйте, beldmit, Вы писали:


B>

B>То есть определить виртуальные методы добавления элемента во внутренний массив и удаления всех элементов?

ДА!

Все методы, которуе могут привести к модификации массива
(Удаление, добаление, изменение ...)
Re[6]: Траблы с CArray
От: beldmit  
Дата: 19.12.02 11:37
Оценка:
Здравствуйте, kmn, Вы писали:

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


kmn>

B>>
B>>То есть определить виртуальные методы добавления элемента во внутренний массив и удаления всех элементов?

kmn>ДА!


kmn>Все методы, которуе могут привести к модификации массива

kmn>(Удаление, добаление, изменение ...)

Это нужно делать только для работы с внутренним массивом — или и с внешним тоже?

И что при этом изменится (а главное — где про это можно прочитать)?

Спасибо!!!
Re[7]: Траблы с CArray
От: LOK Украина  
Дата: 19.12.02 12:12
Оценка:
Здравствуйте, beldmit, :

У Вас один динамически выделяемый массив находится внутри другого ...это не есть гуд..
так как при добавлении данных в подмасив, во время роботы ,происходит перераспределение памяти. И что более всего вероятно где-то происходит повреждение памяти.
... << LOK RSDN@Home 1.0 beta 3 >>
Re[7]: Траблы с CArray
От: kmn Украина  
Дата: 19.12.02 12:27
Оценка:
Здравствуйте, beldmit, Вы писали:


B>Это нужно делать только для работы с внутренним массивом — или и с внешним тоже?



В Вашем случае класс, который вы передаете в DLL, имеет две реализации методов (в DLL и EXE), что уже плохо, так как они могут быть разные (из за настроек проекта).

Поэтому лучше или избавиться от DLL или ввести абстрактный класс.

Если просто объявить функции виртуальными то: две реализации методов все равно останутся, но для конкретного экземпляра класса (благодаря таблицы виртуальных функций) вызовется реализация метода из модуля в котором он был создан.


B>И что при этом изменится (а главное — где про это можно прочитать)?


Я когда-то тоже наступал на эти грабли. Пришлось разбираться, а что делать!!!

Главное помнить:
Блок памяти, выделенный в одном модуле, должен в нем и освобождаться!!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.