![]() |
|
|
![]()
|
|
| mantissa |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
Привет Великий ALL!
Может кто сталкивался с подобным и поможет разобраться в следующем.... имеем: код проги Win32 на С++, Visual MS .net 2003 STL ее же поставки использую контейнер vector<string> (например v) вар.1. после чистки v.clear() вызываю функцию и передаю в ней ссылку на v на 2 вызове после 3 или 4 вставки v.push_back вызывает исключение и программа слетает если всего 2 вставки, то проблем не заметил... вар.2. выношу чистку в ту функцию (ставлю перед циклом) проблема пропадает... все работает НУ КАКАЯ ЕМУ (контейнеру) РАЗНИЦА???? с ув. BSD |
|||
|
||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 1 Всего: 37 |
код в студию.
|
|||
|
||||
| NiJazz |
|
||||
![]() Jazz coder ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2286 Регистрация: 10.8.2003 Где: Москва Репутация: 2 Всего: 23 |
Следующее работало в VS 2k5 SP1:
Добавлено через 1 минуту и 33 секунды Попробуй выставить блок catch ( const std::exception& ex ) и посмотри, что вернёт ex.what(). Например:
|
||||
|
|||||
| Sartorius |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1568 Регистрация: 18.7.2006 Где: Ivory tower Репутация: 1 Всего: 37 |
У меня 2003-я все работает. May be переустановить студию?
|
|||
|
||||
| JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: нет Всего: 162 |
жестоко... ты уверен, что ты до работы с вектором нигде в памяти не накосячил?
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 87 Всего: 183 |
скорее всего. Еще одна возможная причина: DLL + разные экземпляры CRT (например, как статик в каждой DLL) - т.е. кривой проект. -------------------- ... |
|||
|
||||
| mantissa |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
Приветствую всех откликнувшихся!
JackYF > жестоко... ты уверен, что ты до работы с вектором нигде в памяти не накосячил? допустим, но слабо вериться, что вызов метода v.clear() непосредственно перед вставкой способен исправить то, что я накосячил в памяти Earnest> Еще одна возможная причина: DLL + разные экземпляры CRT (например, как статик в каждой DLL) - т.е. кривой проект. вызываемая функция действительно компилируется в DLL... а можно поподробнее... про разные экземпляры CRT и т.д. глюки с DLL уже видел (но в другом проекте), похоже отладчик шел по DLL, созданной DEBUG, а показывал RELEASE версию, но когда очередной STEP вместо функции MessageBox() выполнял CONTINUE на начало цикла, я чуть с кресла не упал.... а насчет кода... попробую выжимки сделать.... файл1 ... namespace { ... vector <string> vcsErrInfo; ... } fun1 { ... case WM_TIMER: ... reread_data(hdlg); ... } fun reread_data() { ... ::vcsErrInfo.clear(); mcr = get_ErrInfo(::vcsErrInfo); ... } file2 ... EXPORT int get_ErrInfo (vector<string>&); ... file3 EXPORT int get_ErrInfo(vector<string>&vcS) { FILE *fil; $ CHAR buf[2048]; //$ CHAR buf1[256]; CHAR szDop[256] = "zero"; fil = fopen("get_ErrInfo.log", "a+"); fprintf(fil, "%s\n", "=============================\n get_ErrInfo: started ..."); fflush(fil); $WHENEVER sqlerror goto ERROR_SQL; lstrcpy(szDop, "declare curs1 cursor"); $declare curs1 cursor with HOLD for select dt||" "||fg||" "||nfile||" "||code||" %1%"||NVL(s_num,"--")||" %2%"||NVL(unum,"--")||" %3%"||NVL(line,"--")||" %4%"||NVL(pos,"--")||" %5%"||NVL(beg_line,"--")||' %6%'||NVL(text,"ОПИСАНИЕ ОТСУТСТВУЕТ")||' %7%'||NVL(kodmes,'---') -- select extend(dt,hour to second)||" "||fg||" "||nfile||" "||code||" %1%"||s_num||" %2%"||NVL(unum,"--")||" %3%"||NVL(line,"--")||" %4%"||NVL(pos,"--")||" %5%"||NVL(beg_line,"--")||' %6%'||NVL(text,"ОПИСАНИЕ ОТСУТСТВУЕТ") -- NVL(s_num,"---")||" "||NVL(unum,"---")||" "||NVL(line,"---")||" "||NVL(pos,"---")||" "||NVL(beg_line,"---")||" "||NVL(text,"ОПИСАНИЕ ОТСУТСТВУЕТ") from tmp_err_info --WHERE inuse = '-' order by dt DESC, fg, nfile --FOR UPDATE OF inuse ; //lstrcpy(szDop, "BEGIN WORK"); //$BEGIN WORK; lstrcpy(szDop, "$open curs1 cursor"); $open curs1; vcS.clear(); // теперича здесь стоит чистка, чтоб работало.... for (INT j=0; ; ++j) { lstrcpy(szDop, "fetch curs1 cursor"); $fetch curs1 into :buf; if (SQLCODE == 100) break; RTrim(buf); fprintf(fil, "%03d)\n", j+1); fprintf(fil, "buf=>%s<\n", buf); fflush(fil); string sTemp = buf; fprintf(fil, "&vcS=%p (%p)\n", &vcS, vcS); vcS.push_back(sTemp); fprintf(fil, "%s\n", "push_back(sTemp=buf) Ok!"); fflush(fil); //$UPDATE tmp_err_info // SET inuse = '+' // WHERE CURRENT OF curs1; } lstrcpy(szDop, "close curs1 cursor"); $close curs1; lstrcpy(szDop, "free curs1 cursor"); $free curs1; //lstrcpy(szDop, "COMMIT WORK"); //$COMMIT WORK; fclose(fil); return 0; //----- $WHENEVER SQLERROR continue; ERROR_SQL: int mcr = SqlMyInfo("get_ErrInfo", szDop); $close curs1; $free curs1; fclose(fil); return mcr; } не успел почистить.... сорри |
|||
|
||||
| JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: нет Всего: 162 |
mantissa, пользуйся кнопками "Код" и "Цитата".
Переформатируй сообщение, читать сложно. |
|||
|
||||
| NiJazz |
|
|||
![]() Jazz coder ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2286 Регистрация: 10.8.2003 Где: Москва Репутация: 2 Всего: 23 |
Память выделенная в одной куче, не может быть освобождена в другой. Как вариант, ты инициализируешь вектор какими-то значениями (выделяешь память), к примеру, в exe, а затем передаёшь вектор по ссылке или указателю в функцию DLL и там вызываешь vector::clear, то есть освобождаешь память. У exe и dll разная куча. Но в то же время, обычно в DEBUG-версии срабатывает ASSERT при подобных ошибках, а не исключение. Для проверки можешь использовать _CrtIsValidHeapPointer( &my_vector[0] ). |
|||
|
||||
| mantissa |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
ТОЧНО! отладчик застревал в кодах STL на попытке высвободить память. а ведь я на похожие грабли уже наступал... СПАСИБО Всем и персональное СПАСИБО NiJazz! и... все равно появляется парочка вопросов.... 1) а как же тогда ListBox (Control) справляется с вставкой и удалением своих строк из разных куч памяти (у него подобных проблем не замечал....) 2) чем чревато то, что объект создан в одной куче, а пользуется памятью чужой? (почему объект не извлекает ссылку на кучу в которой он создан, чтобы забирать память из той же кучи? может это настройки безопасности и их можно где-нибудь выставить в свойствах проекта? ) с ув. BSD |
|||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 3 Всего: 60 |
||||
|
||||
| mantissa |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
опаньки.... и как енто проверить или еще лучше где это в MS VC 2003.net посмотреть? с ув. BSD |
|||
|
||||
| Fazil6 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 3 Всего: 60 |
||||
|
||||
| mantissa |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
Приветствую славную братию программистов!
в свойствах DLL стояло действительно вместо сингла мульти.... исправил на сингл... результат тот же : отладчик указывает на файл "vector"
может нужно какие-нибудь действия при присоединении DLL-ки делать? или не использовать аллокатор по умолчанию в векторе, а назначать какой-нить свой?? в принципе проблема как бы замаскировалась, и про нее м. забыть, делая любые операции с вектором только "по ту сторону баррикад", но я потратил почти 2 дня, пока не замаскировал проблему эмпирическим путем, а поскольку чудес в программировании не бывает и сейчас срочной работой не грузят, как раз есть время разобраться в этом "чуде"... с ув. BSD |
||||
|
|||||
| Fazil6 |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 3 Всего: 60 |
надо не сингл, НАДО ЧТОБЫ ЭТОТ ПАРАМЕТР БЫЛ ОДИНАКОВЫЙ У ВСЕХ, у ддл и у ехе . чуда здесь нет. Вообще передача между модулями объектов(в том числе и STL) не слишком хорошая идея.
ничего тебе тут не поможет. Единственное рабочее решение в таком случае - использовать в ехе и dll один компиллятор, одной и той же версии с одинаковыми настройками. Во Всех других случаях никаких гарантий работоспособности. |
||||
|
|||||
| mantissa |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
Привет, Fazil6 !
были разные, теперь один... не помогает...
дык один он... это вообще один Solution, в который включены 2 проекта (или как там они у него обзываются).... да и на мой взгляд необходимости в DLL-ке вроде нет.... просто мой предшественник все, что относилось к ESQL/C решил засунуть в DLL а почему передача параметров в DLL плохая идея и чем ссылка на объект хуже например указателя на строку? а функции стараюсь писать универсальные, чтобы действительно эту DLL м. было другими EXE-шниками использовать и на мой взгляд проще передать объект, чтобы некто там напихал в него данные, используя его же методы, вместо того, чтобы пихать в объект методы, которые используют вызовы множества ESQL/C функций стоп... перейдем к конкретному примеру.... мне нужно отобразить содержимое файла, хранящееся в БД в BLOB-е и некоторые значения полей таблиц рассмотрим варианты... имеется универсальная функция уже написанная и откомпилированная... ты... 1) просто ее вызовешь с необходимыми параметрами? 2) скопируешь ее код в свой проект? 3) напишешь нечто очень похожее, но свое? как бы ты сам написал эту функцию? 1) передал бы ей кучу хэндлов на окна и пущай в них сама все вставляет 2) забрал бы от нее все данные в статические буфера (для BLOB например 1000К или больше) и сам бы повставлял данные 3) то же но с динамическими буферами (string, vector и т.д.) (кстати вариант там распределять память, а здесь при закрытии окна освобождать - также не проходит по тем же причинам, приходиться выполнять лишние запросы для уточнения размеров) поделись плиз логикой... с ув. BSD |
||||
|
|||||
| Fazil6 |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 3 Всего: 60 |
я говорил о объектах классов. Если у тебя в интерфейсе dll функция, которая в качестве праметра принимает к примеру std::map, то как ты эту функцию будешь вызывать, скажем, в Delphi ? Причем, не факт даже, что программа компиллируемая С++ компиллятором всегда сможет работать с такой dll, просто потому что использует какую-нибудь другую версию STL, потому что объект std::list создаваемый ею отличается в силу особеностей компиллятора от объекта создаваемого компиллятором dll. Объект класса - это ведь не int какой-нибудь.
для этой цели нужно использовать переносимые типы в интерфейсе dll. Использование классов резко сужает область применимости такой библиотеки. см. выше. Для того чтобы напихать в твой объект вызывающий должен знать что это такое и правильно его использовать насчет задачи твоей... Постановка слишком неконкретная. Впринципе возможны любые из приведенных тобой вариантов. Причем здесь dll? Если уж рассматривать некие варианты, то если есть некая либа, которая инкапсулирует, допустим, работу с БД, то функция чтения значения из BLOB записывала бы результат в некий буфер unsigned char* но это далеко не единственное возможное и приемлемое решение. В каждом конкретном случае я буду решать как удобне. У меня тоже есть проекты, которые содержат модули с интерфейсом использующим STL объекты. |
||||
|
|||||
| NiJazz |
|
|||
![]() Jazz coder ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2286 Регистрация: 10.8.2003 Где: Москва Репутация: 2 Всего: 23 |
В данном случае, разная. Не нужно пытаться исправлять ошибку просто обойдя проблему - выставить одинаковый рантайм. Просто не надо выпускать наружу контейнеры STL и всё тут. Используйте копирование, тогда и проблем не будет. Добавлено через 3 минуты и 1 секунду Об отладочной куче можно почитать здесь |
|||
|
||||
| mantissa |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
Привет Все!
Согласен с NiJazz по поводу того, что в 32 битной ОС кучи будут разные, но все равно не понимаю, в чем проблема освободить занимаемую память любой кучи, похоже что для безопасности процессов запрещают насильственными методами (ОС д.б. абсолютно все равно) и второе... что плохого, что вектор находиться в одной куче и содержит объекты, хранящиеся в другой куче?
кто будет распределять память под буфер??? с целью оптимизации было бы выгоднее, чтобы модуль сам распределял память (он то знает какого размера BLOB) (заодно бы и сообщения ползунку слала бы о ходе загрузки), а программа бы в конце высвобождала по этому unsigned char* память. Но так не работает! кстати отказаться от DLL начинает все больше привлекать меня с ув. BSD |
|||
|
||||
| mantissa |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 23.10.2007 Репутация: 1 Всего: 1 |
привет Всем!
более внимательное тестирование показало, что я был не прав, утверждая, что std::string работает без проблем по ссылке в DLL модуле. НИЧЕГО не работает. Ни один объект динамически перераспределяющий память не будет корректно работать с другим потоком учту ошибки в будущем. Всем СПАСИБО! с ув. BSD |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Visual C++/MFC/WTL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |