Есть класс CPatient, один из элементов которого — CVisitArray.
Есть тип CPatientArray — CArray<CPatient, CPatient&>
Один из элементов документа имеет тип CPatientArray. Несколько
переменных-членов CVisit и CPatient имеют тип CString и COLEDateTime,
остальные — фиксированного размера, указателей нет, поэтому деструкторы
пустые.
Указатель на документ передается в плагин(dll), который позволяет
добавлять/редактировать как пациентов, так и визиты. При добавлении визита
все нормально работает, пока не завершается работа приложения. После этого
случается Access Violation. Где копать, чтобы его победить?
Здравствуйте, 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) — грохается.
Здравствуйте, 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, но нет ли более правильного способа?
B>Не очень понимаю. Чем это отличается от обычной передачи указателя в функцию dll для модификации? Я скорее поверю в какую-то ошибку в конструкторе CVisit, из-за чего в память пишется фигня. На этом форуме я нашел похожую проблему — тогда симптомы ошибки исчезали после убирания virtual из описания деструктора, а сама ошибка была следствием выхода где-то за пределы массива. Код живет дома, вечером проверю.
B>Если Вы правы, то что с этим предполагается делать? В принципе этот плагин я могу счесть частью основной функциональности и не совать в dll, но нет ли более правильного способа?
не обращаться к массивам непосредственно
template <class TYPE, class ARG_TYPE = const TYPE&>
class CArrayV
{
public:
virtualint Add(ARG_TYPE v)
{
array.Add(v)
}
virtualint 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;
};
Здравствуйте, kmn, Вы писали:
kmn>Здравствуйте, beldmit, Вы писали:
B>>Если Вы правы, то что с этим предполагается делать? В принципе этот плагин я могу счесть частью основной функциональности и не совать в dll, но нет ли более правильного способа?
kmn>не обращаться к массивам непосредственно
kmn>
Здравствуйте, kmn, Вы писали:
kmn>Здравствуйте, beldmit, Вы писали:
kmn> B>> B>>То есть определить виртуальные методы добавления элемента во внутренний массив и удаления всех элементов?
kmn>ДА!
kmn>Все методы, которуе могут привести к модификации массива kmn>(Удаление, добаление, изменение ...)
Это нужно делать только для работы с внутренним массивом — или и с внешним тоже?
И что при этом изменится (а главное — где про это можно прочитать)?
У Вас один динамически выделяемый массив находится внутри другого ...это не есть гуд..
так как при добавлении данных в подмасив, во время роботы ,происходит перераспределение памяти. И что более всего вероятно где-то происходит повреждение памяти.
B>Это нужно делать только для работы с внутренним массивом — или и с внешним тоже?
В Вашем случае класс, который вы передаете в DLL, имеет две реализации методов (в DLL и EXE), что уже плохо, так как они могут быть разные (из за настроек проекта).
Поэтому лучше или избавиться от DLL или ввести абстрактный класс.
Если просто объявить функции виртуальными то: две реализации методов все равно останутся, но для конкретного экземпляра класса (благодаря таблицы виртуальных функций) вызовется реализация метода из модуля в котором он был создан.
B>И что при этом изменится (а главное — где про это можно прочитать)?
Я когда-то тоже наступал на эти грабли. Пришлось разбираться, а что делать!!!
Главное помнить: Блок памяти, выделенный в одном модуле, должен в нем и освобождаться!!!