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

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

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

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

18.11.2013, 12:45. Просмотров 1792. Ответов 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 жрет память
Посмотрите здесь:

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

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

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

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

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

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

TRY/CATCH - C++
Здравствуйте! У меня есть: MASS; для простоты пояснения, x=rand();y=rand(),znacheniye=rand(); Как игнорировать ошибки...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
13053 / 7316 / 815
Регистрация: 27.09.2012
Сообщений: 18,053
Записей в блоге: 3
Завершенные тесты: 1
18.11.2013, 12:53     Блок try catch жрет память #2
А может где утечка в коде?
ПерС
371 / 287 / 89
Регистрация: 05.11.2013
Сообщений: 820
Записей в блоге: 5
Завершенные тесты: 1
18.11.2013, 12:54     Блок try catch жрет память #3
на сколько увеличивается?
память не обязана освобождаться сразу, маленькими порциями освобождать наоборот было бы невыгодней по ресурсам
SatanaXIII
Супер-модератор
Эксперт С++
5602 / 2636 / 242
Регистрация: 01.11.2011
Сообщений: 6,495
Завершенные тесты: 1
18.11.2013, 13:48     Блок try catch жрет память #4
Цитата Сообщение от Croessmah Посмотреть сообщение
А может где утечка в коде?
Да, покажите код, вызывающий эту утечку.
GibbonCho
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
18.11.2013, 14:03  [ТС]     Блок try catch жрет память #5
Без этого блока память не увеличивается... То есть я создавал 100 потоков и в каждом потоке был один и тот же код например отправки сообщения на сервер, но без try/catch. При первой же ошибке поток закрывался...

Память увеличивается примерно на 200-500 КБ за каждое исключение

Добавлено через 8 минут
А еще я вместо соединения или отправки сообщения в блок try засовывал что угодно, не вызывающее исключение (например тупо цикл)
Код
for(int i=0;i<1000000;i++){
  //что-то например считает
};
и в данном случае память не росла

Значит память растет именно при отлове исключений...

Добавлено через 2 минуты
Кстати, упомянул про ключ /EHa, но забыл спросить, где в билдере его можно указать?)
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
18.11.2013, 15:51     Блок try catch жрет память #6
Цитата Сообщение от GibbonCho Посмотреть сообщение
Значит память растет именно при отлове исключений...
Покажите код внутри try. По симптомам очень похоже, что просто не хватает надлежащих деструкторов, которые будут удалять объекты в случае срабатывания исключения. Например код:

C++
1
2
3
4
5
6
try
{
   init();
   action(); // Если здесь сработает исключение, destroy() не вызовется. 
   destroy();
}
Поэтому надо делать объект, который в конструкторе получает ресурсы, а в деструкторе удаляет.
Почитайте про RAII концепцию, в частности.
rangerx
1932 / 1541 / 141
Регистрация: 31.05.2009
Сообщений: 2,911
18.11.2013, 16:49     Блок try catch жрет память #7
Цитата Сообщение от GibbonCho Посмотреть сообщение
catch(Exception *e)
Каким образом генерируется исключение, что его приходится перехватывать по указателю?
GibbonCho
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
18.11.2013, 16:49  [ТС]     Блок try catch жрет память #8
Цитата Сообщение от Tulosba Посмотреть сообщение
Покажите код внутри try
Код
try{
  smtpClient->Send(message);
}
Вот например отправка инфы подписавшимся... Кстати, проблема действительно похоже не в catch(...)...
Я в try поместил запрос
Код
try{
  HTTP->Get("http://ksfjhgksjfgksjfgh.ru");
}
и не смотря на то, что исключения он ловил, память не росла. Каюсь, неправильно поставил диагноз..
Я так понимаю проблема в smtpClientе... Пользуюсь Indy 10...
Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
19.03.2015, 16:21     Блок try catch жрет память #9
Не знаю, чем закончили ваши изыскания, но у меня похожая проблема.
Вот этот од жрет память.
C++
1
2
3
4
5
6
7
try {
                tmp_data_str = IdHTTP1->Get(tmp_request_str);
            }
            catch (...) {
             ofs<< "исключение http" << std::endl;
//               устройство не найдено.
            }
Если просто
C++
1
tmp_data_str = IdHTTP1->Get(tmp_request_str);
То не жрет, но и не работает- поток выключается.
внутри tmp_request_str находится строка "http://192.168.1.141/dvmh.cgi HTTP/1.1". - 141 меняется в цикле от 0 до 255
Смысл в том, что поток в цикле пробегает по сети и ищет определенные устройства.
Все равботает, но пропадает по 4 кб в 10-20 секунд.
Код, котоырй находится дальше никак не влияет на эту ситуацию, если его весь убрать, все равно память утекает.

На всяий случай весь код:
Кликните здесь для просмотра всего текста
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
    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;
 
    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(tmp_request_str);
            }
            catch (...) {
//               устройство не найдено.
            }
 
            if (tmp_data_str!="")   //ответ не пустой
            if (tmp_data_str[8] == tmp_str_to_comp[1])   //в сети могут быть и другие устройства
                {
                tmp_responce=Form1->DataParcer(tmp_data_str); // разберем ответ, что бы получить ID
 
                if (!Form1->FindDevByID(tmp_responce.dev_id))  // Если устройства с полученным ID нет в списке
                {
                    myDevice* tmp_dev = new myDevice;
                    tmp_dev->dev_ID=tmp_responce.dev_id;
                    tmp_dev->dev_ip=tmp_ip_str;
                    tmp_dev->unavailable_times=0;
                    vec_device_list.push_back(tmp_dev);
                }
 
 
 
        }
            tmp_data_str="";
            is_device_known=false;
        }
 
 
 
Synchronize(UpdateInfo);
    }
MrGluck
Модератор
Эксперт CЭксперт С++
7167 / 4333 / 633
Регистрация: 29.11.2010
Сообщений: 11,777
19.03.2015, 16:45     Блок try catch жрет память #10
C++
1
TIdHTTP *IdHTTP1 = new TIdHTTP;
Запихните в smart pointer.
C++
1
std::unique_ptr<TIdHTTP> IdHTTP1(new TIdHTTP);
Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 00:40     Блок try catch жрет память #11
Цитата Сообщение от MrGluck Посмотреть сообщение
Запихните в smart pointer.
Не помогло. Да и не должно. Он всего 1 раз создается вне цикла.
MrGluck
Модератор
Эксперт CЭксперт С++
7167 / 4333 / 633
Регистрация: 29.11.2010
Сообщений: 11,777
20.03.2015, 00:54     Блок try catch жрет память #12
Ну это единственное место, где явно идёт выделение динамической памяти без освобождения.

А метод Get случайно объекты внутри себя через new не выделяет?
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
20.03.2015, 07:44     Блок try catch жрет память #13
MrGluck, см. 42 строку. Мне кажется в 32й надо просто выйти через return, предварительно освободив idHTTP1.
-=ЮрА=-
Заблокирован
Автор FAQ
20.03.2015, 08:36     Блок try catch жрет память #14
GibbonCho, ели исключение не обработать, а оно не обрабатывается т.к нет e->Delete то и будет течь.
Все пишушие здесь "эксперты подсказчики" реально думают "что скобочки с тремя точечками за вас всю работу сделают"?
единственное что делает "3-х точечный кэтч catch" - сбросит флаг ошибки в тред контексте чтобы треда не дохла, освобождение ресурсов осуществляет конрктеный класс эксепшина и то не всегда
Это код в зубы чтобы понятно было
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
 
int main(){
    char * str;
    system("pause");
    //Пример утечки в 10 Мб
    for( size_t i = 0; i < 10; i++ ){
        try{
            str = new char[1024*1024];
            throw(0);
        }
        catch(...){
            cerr<<"exception #"<<i + 1<<endl;
        }
    }
    system("pause");
    return 0;
}
Миниатюры
Блок try catch жрет память   Блок try catch жрет память  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.03.2015, 08:46     Блок try catch жрет память
Еще ссылки по теме:

Try-catch - C++
Добрый вечер, #include &lt;iostream&gt; using namespace std; void F1(int); void F2(int, int); void F3(int, int, int);

try catch - C++
Здравствуйте. В c++ новичёк, с try catch никогда толком не работал, а тут пришлось. Нужно сделать защиту от ввода всего кроме цифр. вот...

Try catch - C++
try { throw pDoc-&gt;C; } catch (City) { return; } есть динамический City* C, ему присвается значение другого такого...

Try и catch - C++
Пытался сделать простую структуру,чтобы в блоке try задавалось значение переменной x, и если это значение равно,например, 5,то блок catch...

try-catch - C++
Какой тип проекта создавать в Visual Studio чтобы можно было сделать обработку исключений с try-catch? Или что сделать в Code Blocks с той...


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

Или воспользуйтесь поиском по форуму:
-=ЮрА=-
20.03.2015, 08:46     Блок try catch жрет память
  #15

Не по теме:

Цитата Сообщение от rangerx Посмотреть сообщение
Каким образом генерируется исключение, что его приходится перехватывать по указателю?
- почти все виндовые эксепшины так генятся хотябы приславутый CMemoryException
https://msdn.microsoft.com/en-us/library/97z4sxfb.aspx

Yandex
Объявления
20.03.2015, 08:46     Блок try catch жрет память
Ответ Создать тему
Опции темы

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