Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с STL vector, исключение в STL 
V
    Опции темы
mantissa
Дата 23.11.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
Sartorius
Дата 23.11.2007, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 1
Всего: 37



 код в студию.
PM MAIL ICQ   Вверх
NiJazz
Дата 23.11.2007, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


Профиль
Группа: Экс. модератор
Сообщений: 2286
Регистрация: 10.8.2003
Где: Москва

Репутация: 2
Всего: 23



Следующее работало в VS 2k5 SP1:
Код

#include <string>
#include <vector>

void f( std::vector<std::string>& v )
{
    v.push_back( "1" );
    v.push_back( "2" );
    v.push_back( "3" );
    v.push_back( "4" );
}

int _tmain(int argc, _TCHAR* argv[])
{    
    std::vector<std::string> v;

    v.push_back( "1" );
    v.push_back( "2" );
    v.push_back( "3" );

    v.clear();

    f( v );

    return 0;
}


Добавлено через 1 минуту и 33 секунды
Попробуй выставить блок catch ( const std::exception& ex ) и посмотри, что вернёт ex.what(). 
Например:
Код

catch ( const std::exception& ex )
{
   std::cout << ex.what();
}


PM MAIL   Вверх
Sartorius
Дата 23.11.2007, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 1
Всего: 37



 У меня 2003-я все работает. May be переустановить студию?
PM MAIL ICQ   Вверх
JackYF
Дата 23.11.2007, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: нет
Всего: 162



жестоко... ты уверен, что ты до работы с вектором нигде в памяти не накосячил?



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Earnest
Дата 25.11.2007, 13:10 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(JackYF @  23.11.2007,  23:21 Найти цитируемый пост)
жестоко... ты уверен, что ты до работы с вектором нигде в памяти не накосячил?

скорее всего.
Еще одна возможная причина: DLL + разные экземпляры CRT (например, как статик в каждой DLL) - т.е. кривой проект.



--------------------
...
PM   Вверх
mantissa
Дата 26.11.2007, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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;
}
 не успел почистить.... сорри

PM MAIL   Вверх
JackYF
Дата 26.11.2007, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: нет
Всего: 162



mantissa, пользуйся кнопками "Код" и "Цитата".
Переформатируй сообщение, читать сложно.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
NiJazz
Дата 26.11.2007, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


Профиль
Группа: Экс. модератор
Сообщений: 2286
Регистрация: 10.8.2003
Где: Москва

Репутация: 2
Всего: 23



Цитата
а можно поподробнее... про  разные экземпляры CRT и т.д.

Память выделенная в одной куче, не может быть освобождена в другой. Как вариант, ты инициализируешь вектор какими-то значениями (выделяешь память), к примеру, в exe, а затем передаёшь вектор по ссылке или указателю в функцию DLL и там вызываешь vector::clear, то есть освобождаешь память. У exe и dll разная куча. 
Но в то же время, обычно в DEBUG-версии срабатывает ASSERT при подобных ошибках, а не исключение. Для проверки можешь использовать _CrtIsValidHeapPointer( &my_vector[0] ).

PM MAIL   Вверх
mantissa
Дата 27.11.2007, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 23.10.2007

Репутация: 1
Всего: 1



Цитата

Память выделенная в одной куче, не может быть освобождена в другой. Как вариант, ты инициализируешь вектор какими-то значениями (выделяешь память), к примеру, в exe, а затем передаёшь вектор по ссылке или указателю в функцию DLL и там вызываешь vector::clear, то есть освобождаешь память. У exe и dll разная куча. 
Но в то же время, обычно в DEBUG-версии срабатывает ASSERT при подобных ошибках, а не исключение. Для проверки можешь использовать _CrtIsValidHeapPointer( &my_vector[0] ).


ТОЧНО! отладчик застревал в кодах STL на попытке высвободить память.
а ведь я на похожие грабли уже наступал...
СПАСИБО Всем и персональное СПАСИБО NiJazz!

и... все равно появляется парочка вопросов....
1) а как же тогда ListBox (Control) справляется с вставкой и удалением своих строк из разных куч памяти (у него подобных проблем не замечал....)
2) чем чревато то, что объект создан в одной куче, а пользуется памятью чужой? (почему объект не извлекает ссылку на кучу в которой он создан, чтобы забирать память из той же кучи? может это настройки безопасности и их можно где-нибудь выставить в свойствах проекта? )

с ув. BSD
PM MAIL   Вверх
Fazil6
Дата 27.11.2007, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 3
Всего: 60



Цитата(mantissa @  27.11.2007,  16:32 Найти цитируемый пост)
 У exe и dll разная куча.

неверно. У exe и dll одна куча. Проблема кроется когда exe и dll скомпиллированы с разными версиями CRT и когда объект создается в одном модуле(одной версией CRT), а удаляется в другом модуле(другой версией CRT) получаем ошибку
PM MAIL   Вверх
mantissa
Дата 27.11.2007, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 23.10.2007

Репутация: 1
Всего: 1



Цитата

неверно. У exe и dll одна куча. Проблема кроется когда exe и dll скомпиллированы с разными версиями CRT и когда объект создается в одном модуле(одной версией CRT), а удаляется в другом модуле(другой версией CRT) получаем ошибку


опаньки.... и как енто проверить или еще лучше где это в MS VC 2003.net посмотреть?

с ув. BSD
PM MAIL   Вверх
Fazil6
Дата 27.11.2007, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 3
Всего: 60



вот так

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  prop.JPG 55,92 Kb
PM MAIL   Вверх
mantissa
Дата 29.11.2007, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 23.10.2007

Репутация: 1
Всего: 1



Приветствую славную братию программистов!

Цитата

вот так

Присоединённый файл ( Кол-во скачиваний: 4 ) 


 в свойствах DLL стояло действительно вместо сингла мульти....
исправил на сингл...
результат тот же :

отладчик указывает на файл "vector"
Код

    iterator insert(iterator _Where, const _Ty& _Val)
        {    // insert _Val at _Where
        size_type _Off = size() == 0 ? 0 : _Where - begin();
        _Insert_n(_Where, (size_type)1, _Val);
        return (begin() + _Off);                                  // << сыпется здесь!
        }



может нужно какие-нибудь действия при присоединении DLL-ки делать?
или не использовать аллокатор по умолчанию в векторе, а назначать какой-нить свой??

в принципе проблема как бы замаскировалась, и про нее м. забыть, делая любые операции с вектором только "по ту сторону баррикад",
но я потратил почти 2 дня, пока не замаскировал проблему эмпирическим путем, а поскольку чудес в программировании не бывает и сейчас срочной работой не грузят, как раз есть время разобраться в этом "чуде"...

с ув. BSD
PM MAIL   Вверх
Fazil6
Дата 29.11.2007, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 3
Всего: 60



Цитата(mantissa @  29.11.2007,  16:37 Найти цитируемый пост)
 в свойствах DLL стояло действительно вместо сингла мульти....исправил на сингл...результат тот же :

надо не сингл, НАДО ЧТОБЫ ЭТОТ ПАРАМЕТР БЫЛ ОДИНАКОВЫЙ У ВСЕХ, у ддл и у ехе

.
Цитата(mantissa @  29.11.2007,  16:37 Найти цитируемый пост)
в принципе проблема как бы замаскировалась, и про нее м. забыть, делая любые операции с вектором только "по ту сторону баррикад",но я потратил почти 2 дня, пока не замаскировал проблему эмпирическим путем, а поскольку чудес в программировании не бывает и сейчас срочной работой не грузят, как раз есть время разобраться в этом "чуде"...

чуда здесь нет. Вообще передача между модулями объектов(в том числе и STL) не слишком хорошая идея.  
Цитата(mantissa @  29.11.2007,  16:37 Найти цитируемый пост)
может нужно какие-нибудь действия при присоединении DLL-ки делать?или не использовать аллокатор по умолчанию в векторе, а назначать какой-нить свой??

ничего тебе тут не поможет. Единственное рабочее решение в таком случае - использовать в ехе и dll один компиллятор, одной и той же версии с одинаковыми настройками. Во Всех других случаях  никаких гарантий работоспособности.


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.1227 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.