Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
GibbonCho
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
#1

Блок try catch жрет память - C++

18.11.2013, 12:45. Просмотров 1806. Ответов 48
Метки нет (Все метки)

Доброго времени суток! Проблема случилась там, где ее никак не ожидал, ответа ни в поисковиках, ни на форумах не нашел. Вся надежда на вас!

в общем есть блок
C++
1
2
3
4
5
try{
  //код, соединения с сервером или отправки сообщения серверу
} catch(Exception *e){
  //обработка ошибки подключения или отправки
}
Так вот при каждом исключении увеличивается память (в диспетчере задач).
Среда : C++ Builder 6

Без блока try catch память не растет, но приложение при ошибке перестает работать, естественно.
Читал о том, что в c++ у блока catch отсутствует деструктор. Еще читал про то, что если поставить ключ компиляции /EHa, то catch не будет кушать память..
Помогите, пожалуйста, весь интернет перерыл, не могу найти ответ.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2013, 12:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Блок try catch жрет память (C++):

Программа с opencv жрет память - C++
Вообщем есть программа, после каждой итерации очищаю память, но все-равно почему то буквально за 2-3 цикла по j, программа падает из-за...

Блок try-catch - C++
В некоторых программах он хорошо работает и в блоке catch выводит то что написал, а в некоторых среда VS говорит "Необработанное исключение...

Работает ли указатель на базовый класс исключения, когда попадает в блок catch - C++
Работает ли указатель на базовый класс исключения, когда попадает в блок catch так же как обычно? То есть, если есть переопределенные...

Как передать управление в блок catch после системного исключения (компилятор g++)? - C++
Вот пример: не удаётся это сделать #include <windows.h> #include <stdio.h> //Эта функция- НОВЫЙ обработчик...

Один блок catch для двух типов исключений порожденных от одного класса - C++
Товагищи!! Имеется задача с книги С. Прата с++11. Не могу реализовать следующее : Вот к чему пришел #include <iostream> #include...

Как записать блок данных в память ? - C++
Есть ли какая нибудь функция типа fwrite(), которая может писать блоки данных разной длины, но из памяти в память ? Например есть...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Croessmah
20.03.2015, 09:02     Блок try catch жрет память
  #16

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Все пишушие здесь "эксперты подсказчики" реально думают "что скобочки с тремя точечками за вас всю работу сделают"?
По себе людей не судят, да ведь?
-=ЮрА=-, все дибилы, один ты умный, всех лучше и вообще паинька, судя по постам на форуме.
Это не только в этой теме. Постоянно от тебя льется куча слов о том, какой ты умный, а остальные дауны.

-=ЮрА=-
20.03.2015, 09:13
  #17

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
По себе людей не судят, да ведь?
-=ЮрА=-, все дибилы, один ты умный, всех лучше и вообще паинька, судя по постам на форуме.
Это не только в этой теме. Постоянно от тебя льется куча слов о том, какой ты умный, а остальные дауны.
- лично против тебя я ничего не имею(по крайней мере пока), я написал свой пост ряду людей с пометкой "exсперт", которые имели обыкновение меня задеть, попытаться потролить - ну вот с этого момента такой человек для меня перестаёт существовать. Касательно темы как бы 10 постов поисков "где же течёт" явно указывает на уровень "псевдоэксперт", меня тут почему то каждое г. пытается помазать грязью, хотя я подольше любого в этой теме на форуме и на много больше людям помог(и заметь никого 1-м никода не тронул, раз ты такой поборник справедливости, будь добр посёрфись по форуму, да погляди темы, кто где как и с какими словами начинал) - так что у меня свои методы восстановления справедливости.

Voivoid
674 / 277 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
20.03.2015, 10:05 #18
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
освобождение ресурсов осуществляет конрктеный класс эксепшина и то не всегда
Э-э-э, что?
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
20.03.2015, 11:01 #19
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Все пишушие здесь "эксперты подсказчики" реально думают "что скобочки с тремя точечками за вас всю работу сделают"?
единственное что делает "3-х точечный кэтч catch" - сбросит флаг ошибки в тред контексте чтобы треда не дохла, освобождение ресурсов осуществляет конрктеный класс эксепшина и то не всегда
Что? Освобождение ресурсов осуществляет конкретный класс эксепшна? Только если ресурсов выделенных внутри данного класса исключения...

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
так что у меня свои методы восстановления справедливости.
Справедливость должна быть восстановлена! (c) Утер Светоносный

Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 11:54 #20
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
ели исключение не обработать, а оно не обрабатывается т.к нет e->Delete то и будет течь.
К сожалению, ты ответил на тему 3х летней давности. Я написал в ней же, у меня схожая проблема, но никого new в try нет. Никакой динамики в икле нет, а память уходит... Мой код на пару сообщений выше
MakeEasy
39 / 39 / 13
Регистрация: 24.02.2015
Сообщений: 151
20.03.2015, 12:23 #21
Dreablin, Может быть подключения висят и в экспешене не закрываются. Можно попробовать убрать keep-alive :
C++
1
IdHTTP1->Request->Connection= "keep-alive";
Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 13:13 #22
Цитата Сообщение от MakeEasy Посмотреть сообщение
Может быть подключения висят и в экспешене не закрываются. Можно попробовать убрать keep-alive :
Хорошая идея, но не прокатило ((
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
20.03.2015, 14:21 #23
Цитата Сообщение от Dreablin Посмотреть сообщение
То не жрет, но и не работает- поток выключается.
Потому что необработанное исключение, которое возникает в Get() отправляется на уровень выше, до того момента пока не встретит соответствующего обработчика. А если не встретит, то и вовсе будет вызван какой-нибудь std::terminate, который приведет к закрытию программы.
Когда ты добавляешь перехват всего и вся catch (...) не добавив внутри обработчика ничего вразумительного (код ты не привел по крайней мере), и не сделав выхода из функции или хотя бы из цикла, ты попадаешь на строки 35 и далее. В частности в 42 строке у тебя создается в куче элемент, указатель на который ты добавляешь в vec_device_list. С листом тоже не понятно что дальше происходит, удаляешь ты потом его элементы или нет (снова нет кода).
В первом приближении решение твоей задачи я описать чуть выше. Процитирую себя же:
Цитата Сообщение от Tulosba Посмотреть сообщение
Мне кажется в 32й надо просто выйти через return, предварительно освободив idHTTP1.
Сделай это и проверь как будут вести себя утечки. Если не поможет - приводи больше кода.

Добавлено через 43 секунды

Не по теме:

Цитата Сообщение от Dreablin Посмотреть сообщение
ты ответил на тему 3х летней давности.
В частности поэтому следует создавать новую тему.

Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 14:49 #24
Цитата Сообщение от Tulosba Посмотреть сообщение
В частности в 42 строке у тебя создается в куче элемент, указатель на который ты добавляешь в vec_device_list. С листом тоже не понятно что дальше происходит, удаляешь ты потом его элементы или нет (снова нет кода).
С листом происходит следующее - его опрашивает в цикле другой поток. Т.е. он никогда не должен удаляться впринципе. Если устройство подключено, оно будет работать без перерывов. Механизм удаления предусмотрен, если устройсвто пропадает, но это делает другой поток. Больше того, Если в сети вообще нет устройств (т.е. в 42ю строку мы не попадаем). Расписав все Catch, как это было в самом начале:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//catch(EIdSocketError &E)  // Исключения сокетов
// {
//   ShowMessage("Ошибка:\n\""+E.Message+"\"");
// }
//catch(EIdHTTPProtocolException &E)
// {
//   // Можно получить код ответа сервера  HTTP  через E.ErrorCode
//      ShowMessage(String(E.ErrorCode)+" "+E.Message); break;
//  }
//catch(EIdException &E)// Другие исключения Indy
//  {
//   ShowMessage("Ошибка:\n\""+E.Message+"\"");
//  }
//catch(Exception &E)   // Другие НЕ Indy искключения
//  {
//  ShowMessage("Ошибка:\n\""+E.Message+"\"");
//  }

Вылетает ошибка "Connection time out". Ошибка возникает уже на 192.168.1.1 и если выходить через return, то смысла с этого потока?
И это весь код. Бежит по сети, находит - добавляет.
Я создал новый проект с таким кодом:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    int tmp_device_num;
    bool is_device_known=false;
    UnicodeString tmp_data_str="";
    UnicodeString tmp_ip_str;
    UnicodeString tmp_request_str;
    UnicodeString tmp_str_to_comp="Emfit";
    UnicodeString tmp_dev_ID;
 
//  myDeviceResponse tmp_responce;
 
//  std::unique_ptr<TIdHTTP> IdHTTP1(new TIdHTTP);
    TIdHTTP *IdHTTP1 = new TIdHTTP;
 
    IdHTTP1->Request->UserAgent= "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0";
    IdHTTP1->Request->Accept= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    IdHTTP1->Request->AcceptLanguage= "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3";
    IdHTTP1->Request->AcceptEncoding= "gzip, deflate";
//  IdHTTP1->Request->Connection= "keep-alive";
    IdHTTP1->Request->CacheControl= "max-age=0";
    IdHTTP1->ConnectTimeout = 100;
 
while (1)
 {
        for (size_t i = 1; i < 255; i++)
        {
            tmp_ip_str= base_ip_str+(UnicodeString)i ;
            tmp_request_str="http://"+tmp_ip_str+"/dvmh.cgi HTTP/1.1";
 
            IdHTTP1->Request->Host=tmp_ip_str;
            try {
              tmp_data_str = IdHTTP1->Get("http://192.168.1.149/dvmh.cgi HTTP/1.1");
            }
//          catch (...) {
//           ofs<< "исключение http" << std::endl;
//               устройство не найдено.
//          }
catch(EIdSocketError &E)  // Исключения сокетов
 {
   ShowMessage("Ошибка:\n\""+E.Message+"\"");
 }
catch(EIdHTTPProtocolException &E)
 {
   switch(E.ErrorCode)
      {
        ShowMessage(String(E.ErrorCode)+" "+E.Message); break;
      }
  }
catch(EIdException &E)// Другие исключения Indy
  {
     ShowMessage("Ошибка:\n\""+E.Message+"\"");
  }
catch(Exception &E)   // Другие НЕ Indy искключения
  {
    ShowMessage("Ошибка:\n\""+E.Message+"\"");
  }
 
catch(...)   // Другие искключения
  {
    ShowMessage("Ошибка");
  }
}
 
}


Он опрашиваетадрес, по которому точно нет устройства. Ошиба с таймаутом есть и память жрет.
Если поставить адрес, где устройство есть, память не жрет.
Проблема, значит в connection time out - где-то остается висеть соединение... Но где?...
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
20.03.2015, 15:17 #25
Цитата Сообщение от Dreablin Посмотреть сообщение
Вылетает ошибка "Connection time out".
Это по какому типу исключения?
Строку 45 надо убрать, и break в 48. Иначе это глупая конструкция.
Цитата Сообщение от Dreablin Посмотреть сообщение
и память жрет.
Кстати, чем ты это наблюдаешь и какой порядок жора?
Сдается мне, проблема твоя скорее всего в неправильной работе с Indy компонентами. Хотя может и в самих компонентах баг.

Добавлено через 4 минуты
Цитата Сообщение от Dreablin Посмотреть сообщение
Проблема, значит в connection time out
Кстати, посмотри каким-нибудь ProcessExplorer список TCP-соединений у процесса.
Чтобы точно понять они плодятся или нет.

Добавлено через 2 минуты
Ну и ещё, возможно в случае неудачи имеет смысл подождать (Sleep) прежде чем снова ломиться (Get) в ту же самую дырку.
Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 15:34 #26
Цитата Сообщение от Tulosba Посмотреть сообщение
Это по какому типу исключения?
C++
1
2
3
4
catch(EIdException &E)// Другие исключения Indy
  {
     ShowMessage("Ошибка2:\n\""+E.Message+"\"");
  }
Цитата Сообщение от Tulosba Посмотреть сообщение
Кстати, чем ты это наблюдаешь и какой порядок жора?
Наблюдаю windows explorerом стандратным. Порядок 1 мб в 2-3 часа
Цитата Сообщение от Tulosba Посмотреть сообщение
Кстати, посмотри каким-нибудь ProcessExplorer список TCP-соединений у процесса.
Тот же монитор ресурсов показывает целый список TCP соединений у процесса... Не столько, сольок их должно быть при такой работе, но все равно десятки. Видимо рано или поздно соединения закрываются на другом уровне, а вот память не освобождается....
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
20.03.2015, 15:57 #27
Цитата Сообщение от Dreablin Посмотреть сообщение
1 мб в 2-3 часа
И сколько итераций цикла за эти 2-3 часа проходит?
Любопытно как ты вообще обратил внимание на этот мегабайт за 2 часа.
Цитата Сообщение от Dreablin Посмотреть сообщение
Наблюдаю windows explorerом стандратным
Ты наверное имел в виду TaskManager?
Цитата Сообщение от Dreablin Посмотреть сообщение
рано или поздно соединения закрываются на другом уровне, а вот память не освобождается....
Есть такое понятие как "полуоткрытое" соединение. Это когда запрос о TCP подключении отправили, а ответа не получили ещё (SYN_WAIT вроде называется состояние). Разумеется эти соединения кушают какую-то память (пока они висят в ожидании), но если они завершились по причине таймаута, то утечек быть не должно. Т.к. это всё на уровне стека TCP/IP обеспечивается, а не в клиентской части программы.

Таким образом твои утечки может быть и не утечки вовсе, а естественный расход на поддержку N-го кол-ва полуоткрытых соединений.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
20.03.2015, 16:00 #28
Цитата Сообщение от ПерС Посмотреть сообщение
память не обязана освобождаться сразу, маленькими порциями освобождать наоборот было бы невыгодней по ресурсам
С чего это?
Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 16:09 #29
Цитата Сообщение от Tulosba Посмотреть сообщение
Любопытно как ты вообще обратил внимание на этот мегабайт за 2 часа.
Тестированием на ночь, например. Да и видно само по себе. Съедает 4кб за 10-30 секунд, примерно.
Если вечером оставить уже будет 6 мб вместо 2х.
Если еще не понятно, этот код должен работать неограниченное время.
Цитата Сообщение от Tulosba Посмотреть сообщение
Таким образом твои утечки может быть и не утечки вовсе, а естественный расход на поддержку N-го кол-ва полуоткрытых соединений.
Сомнительно. Оставлял работать на 4-5 дней, записал в базу около 5 млн записей, все работает. Но расход памяти был стабильный. Это именно утечка и происходит она во время исключения GET при обработе его в Catch.
Возможно, дело можно решить настройкой Indy, что бы вместо connection time out, соединение автоматически закрывалось, если нет ответа.... Пока не нашел выход.
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
20.03.2015, 16:18 #30
Цитата Сообщение от Dreablin Посмотреть сообщение
Съедает 4кб за 10-30 секунд,
Лучше посчитать именно на кол-во итераций цикла, секунды ничего не говорят, если не знаешь сколько раз действие было выполнено на это время.
Цитата Сообщение от Dreablin Посмотреть сообщение
Оставлял работать на 4-5 дней,
Т.е. за 5 суток ~60 метров набегало в плюс?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.03.2015, 16:18
Привет! Вот еще темы с ответами:

много памяти жрет игра на OpenGL - C++
много памяти жрет игра на OpenGL...через диспетчер смотрю аж 15 метров...там же ничего особого нету...или так и должно быть??? ...

Браузер Awesomium жрет память - C# WPF
Всем здравствуйте, у меня в программе используется компонент awesomium замечено что на некоторых сайтах (если долго открыт браузер) память...

Что то жрет оперативную память - Windows 7
мне посоветовали обратиться сюда насчет этой темыhttp://www.cyberforum.ru/viruses/thread1495290.html где мы не смогли найти решение может...

Отрисовка в таймере жрет память - OpenGL
Программа написанная на OpenGL понемногу, но непрерывно ест RAM. А именно после того как я юзаю таймер вида void Timer( int value ){...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
20.03.2015, 16:18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru