В Visual Studio 2010 постоянно вылетает программа, а именно процедура test при ее вызове.
Привожу упрощенную версию кода, которая не работает.
Заголовочный файл.
--------------------------------------------------------------------------------------------------------------
// MathEx.h: interface for the CMathEx class.
//////////////////////////////////////////////////////////////////////
Здравствуйте, ahaos, Вы писали:
A>После выполнения return в функции test программа вылетает. В предыдущих версиях VS это прекрасно работало. В чем может быть дело. A>Ясно, что в реальности в процедуре test вектор res заполняется полезными данными и должен быть возвращен вызывающей программе.
Если эти полезные данные static или глобальные, то дело может быть в порядке инициализации.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, ahaos, Вы писали:
A>>После выполнения return в функции test программа вылетает. В предыдущих версиях VS это прекрасно работало. В чем может быть дело. A>>Ясно, что в реальности в процедуре test вектор res заполняется полезными данными и должен быть возвращен вызывающей программе.
BFE>Если эти полезные данные static или глобальные, то дело может быть в порядке инициализации.
Дело не в данных. Дело в том, что и в приведенном виде эта программа также вылетает. А здесь я только задаю размер вектора и все — никакой связи с данными нет. Вылет программы, как я понял, происходит в деструкторе класса vector при выходе из процедуры. Причем это деструктор не того вектора, который в процедуре указан, а какого-то промежуточного — наверное того, который возвращается.
Заметил вот, что такой код работает:
1.
vector<int> v;
v=CMathEx::test();
2.
а такой нет:
CMathEx::test();
Хотя код номер 2 работать должен. Несмотря на то, что код 1 работает, мне кровь из носа нужно заставить работать код номер 2. Зачем, не спрашивайте — это нужно смотреть реальную программу. Там действительно из-за этого серьезная проблема, а перекодирование равносильно цунами.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, ahaos, Вы писали:
A>>Дело не в данных. Дело в том, что и в приведенном виде эта программа также вылетает. BFE>С какой диагностикой?
Вылетает он на этой функции.
extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
const void * pUserData
)
{
if (!pUserData)
return FALSE;
if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE))
return FALSE;
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, ahaos, Вы писали:
A>>Вылетает он на этой функции. A>>extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
BFE>Возможно Ops прав. Попробуйте release собрать, для начала.
В релизной версии на этом месте вылет:
Сигнатура проблемы:
Имя события проблемы: APPCRASH
Имя приложения: haos.exe
Версия приложения: 1.0.0.1
Отметка времени приложения: 4e392f01
Имя модуля с ошибкой: ntdll.dll
Версия модуля с ошибкой: 6.1.7600.16385
Отметка времени модуля с ошибкой: 4a5bdb3b
Код исключения: c0000005
Смещение исключения: 0002e29b
Версия ОС: 6.1.7600.2.0.0.256.1
Код языка: 1049
Дополнительные сведения 1: 0a9e
Дополнительные сведения 2: 0a9e372d3b4ad19135b953a78882e789
Дополнительные сведения 3: 0a9e
Дополнительные сведения 4: 0a9e372d3b4ad19135b953a78882e789
Здравствуйте, ahaos, Вы писали:
A>В Visual Studio 2010 постоянно вылетает программа, а именно процедура test при ее вызове. A>Привожу упрощенную версию кода, которая не работает.
A>Заголовочный файл. bla-bla-bla...
A>Вызов процедуры test из основной программы.
A>CMathEx::test();
A>После выполнения return в функции test программа вылетает. В предыдущих версиях VS это прекрасно работало. В чем может быть дело.
A>Ясно, что в реальности в процедуре test вектор res заполняется полезными данными и должен быть возвращен вызывающей программе.
На всякий случай спрошу...
Место вызова и реализация CMathEx::test() находятся в одном модуле или разных? Runtime-library статически прилинковано или используется msvcrtXX.dll?
Мои предположения (если используются разные модули):
1. выделение памяти в одном Runtime, а освобождение — в другом.
2. Один модуль компилится с одними настройками, второй с другими. Например, разные объявления _SECURE_SCL, _HAS_ITERATOR_DEBUGGING
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Здравствуйте, ahaos, Вы писали:
A>>В Visual Studio 2010 постоянно вылетает программа, а именно процедура test при ее вызове. A>>Привожу упрощенную версию кода, которая не работает.
A>>Заголовочный файл. bla-bla-bla...
A>>Вызов процедуры test из основной программы.
A>>CMathEx::test();
A>>После выполнения return в функции test программа вылетает. В предыдущих версиях VS это прекрасно работало. В чем может быть дело.
A>>Ясно, что в реальности в процедуре test вектор res заполняется полезными данными и должен быть возвращен вызывающей программе.
SVZ>На всякий случай спрошу... SVZ>Место вызова и реализация CMathEx::test() находятся в одном модуле или разных? Runtime-library статически прилинковано или используется msvcrtXX.dll?
SVZ>Мои предположения (если используются разные модули): SVZ>1. выделение памяти в одном Runtime, а освобождение — в другом. SVZ>2. Один модуль компилится с одними настройками, второй с другими. Например, разные объявления _SECURE_SCL, _HAS_ITERATOR_DEBUGGING
Да модули разные. Используется статическая линковка библиотек. Я сейчас перетянул этот файл в главный модуль и все заработало.
Только как эту проблему решить я пока не понял. Настройки я конечно покопаю, а в первом случае что делать?
Здравствуйте, ahaos, Вы писали:
SVZ>>Мои предположения (если используются разные модули): SVZ>>1. выделение памяти в одном Runtime, а освобождение — в другом. SVZ>>2. Один модуль компилится с одними настройками, второй с другими. Например, разные объявления _SECURE_SCL, _HAS_ITERATOR_DEBUGGING
A>Да модули разные. Используется статическая линковка библиотек. Я сейчас перетянул этот файл в главный модуль и все заработало. A>Только как эту проблему решить я пока не понял. Настройки я конечно покопаю, а в первом случае что делать?
Использовать один рантайм в обоих модулях. Включи в настройках проекта "Multithreaded (Debug) DLL" (ключи компилятора /MD или /MDd).
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Здравствуйте, ahaos, Вы писали:
SVZ>>>Мои предположения (если используются разные модули): SVZ>>>1. выделение памяти в одном Runtime, а освобождение — в другом. SVZ>>>2. Один модуль компилится с одними настройками, второй с другими. Например, разные объявления _SECURE_SCL, _HAS_ITERATOR_DEBUGGING
A>>Да модули разные. Используется статическая линковка библиотек. Я сейчас перетянул этот файл в главный модуль и все заработало. A>>Только как эту проблему решить я пока не понял. Настройки я конечно покопаю, а в первом случае что делать?
SVZ>Использовать один рантайм в обоих модулях. Включи в настройках проекта "Multithreaded (Debug) DLL" (ключи компилятора /MD или /MDd).
Насколько я понял /MD подразумевает динамическую линковку, что нежелательно. Сейчас у меня стоит во всех модуля /MT и не работает.
Здравствуйте, ahaos, Вы писали:
SVZ>>Использовать один рантайм в обоих модулях. Включи в настройках проекта "Multithreaded (Debug) DLL" (ключи компилятора /MD или /MDd).
A>Насколько я понял /MD подразумевает динамическую линковку, что нежелательно. Сейчас у меня стоит во всех модуля /MT и не работает.
Ну естественно, работать не будет. В DLL у тебя один рантайм, в EXE — другой. Память, выделенная одним рантаймом, не может быть освобождена другим.
Собственно, у тебя три варианта:
1. использовать один общий рантайм (динамическая линковка)
2. втягивать весь код в один модуль
3. Перепроектировать интерфейс так, чтобы память выделялась и освобождалась только в своем модуле. Т.е. никаких vector, string и проч. в интерфейсе быть не должно — в exe выделили буфер, передали указатель в dll, там буфер заполняется, после использования exe этот буфер удаляет. pure-C style.
4. СОМ интерфейсы (этот вариант здесь ИМХО лишний).
_____________________
С уважением,
Stanislav V. Zudin
On 03.08.2011 19:23, ArtDenis wrote:
> C>Классы C++ нельзя передавать через границу DLL. > > Ничего подобного. Можно передавать с некоторыми ограничениями.
В нормальных проектах можно передавать объекты классов и ссылки на
них без всяких ограничений через границу DLL-ей.
Здравствуйте, MasterZiv, Вы писали:
MZ>В нормальных проектах можно передавать объекты классов и ссылки на MZ>них без всяких ограничений через границу DLL-ей.
Ну-ну...
Тут уже говорили о рантайме, который занимается управлением памятью и о том, что он должен быть общим для тех, кто создаёт класс и кто его уничтожает. Это одно из ограничений.
Другое ограничение — это соблюдение что-то типа ODR для используемых классов. Другими словами при изменении структуры класса, надо перекомпилировать все исполняемые и подключаемые модули, где этот класс используется.