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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
GibbonCho
0 / 0 / 0
Регистрация: 18.11.2013
Сообщений: 16
18.11.2013, 12:45     Блок try catch жрет память #1
Доброго времени суток! Проблема случилась там, где ее никак не ожидал, ответа ни в поисковиках, ни на форумах не нашел. Вся надежда на вас!

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

Без блока try catch память не растет, но приложение при ошибке перестает работать, естественно.
Читал о том, что в c++ у блока catch отсутствует деструктор. Еще читал про то, что если поставить ключ компиляции /EHa, то catch не будет кушать память..
Помогите, пожалуйста, весь интернет перерыл, не могу найти ответ.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
18.11.2013, 12:53     Блок try catch жрет память #2
А может где утечка в коде?
ПерС
366 / 282 / 84
Регистрация: 05.11.2013
Сообщений: 806
Записей в блоге: 5
Завершенные тесты: 1
18.11.2013, 12:54     Блок try catch жрет память #3
на сколько увеличивается?
память не обязана освобождаться сразу, маленькими порциями освобождать наоборот было бы невыгодней по ресурсам
SatanaXIII
Супер-модератор
Эксперт С++
 Аватар для SatanaXIII
5549 / 2563 / 233
Регистрация: 01.11.2011
Сообщений: 6,337
Завершенные тесты: 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
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
18.11.2013, 15:51     Блок try catch жрет память #6
Цитата Сообщение от GibbonCho Посмотреть сообщение
Значит память растет именно при отлове исключений...
Покажите код внутри try. По симптомам очень похоже, что просто не хватает надлежащих деструкторов, которые будут удалять объекты в случае срабатывания исключения. Например код:

C++
1
2
3
4
5
6
try
{
   init();
   action(); // Если здесь сработает исключение, destroy() не вызовется. 
   destroy();
}
Поэтому надо делать объект, который в конструкторе получает ресурсы, а в деструкторе удаляет.
Почитайте про RAII концепцию, в частности.
rangerx
1908 / 1517 / 139
Регистрация: 31.05.2009
Сообщений: 2,876
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
Ворчун
Эксперт С++
 Аватар для MrGluck
4927 / 2670 / 243
Регистрация: 29.11.2010
Сообщений: 7,429
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
Ворчун
Эксперт С++
 Аватар для MrGluck
4927 / 2670 / 243
Регистрация: 29.11.2010
Сообщений: 7,429
20.03.2015, 00:54     Блок try catch жрет память #12
Ну это единственное место, где явно идёт выделение динамической памяти без освобождения.

А метод Get случайно объекты внутри себя через new не выделяет?
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
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 жрет память  
-=ЮрА=-
20.03.2015, 08:46
  #15

Не по теме:

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

Croessmah
20.03.2015, 09:02
  #16

Не по теме:

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

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

Не по теме:

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

Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,284
20.03.2015, 10:05     Блок try catch жрет память #18
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
освобождение ресурсов осуществляет конрктеный класс эксепшина и то не всегда
Э-э-э, что?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
20.03.2015, 11:01     Блок try catch жрет память #19
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Все пишушие здесь "эксперты подсказчики" реально думают "что скобочки с тремя точечками за вас всю работу сделают"?
единственное что делает "3-х точечный кэтч catch" - сбросит флаг ошибки в тред контексте чтобы треда не дохла, освобождение ресурсов осуществляет конрктеный класс эксепшина и то не всегда
Что? Освобождение ресурсов осуществляет конкретный класс эксепшна? Только если ресурсов выделенных внутри данного класса исключения...

Не по теме:

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

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.03.2015, 11:54     Блок try catch жрет память
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Dreablin
5 / 5 / 1
Регистрация: 05.02.2010
Сообщений: 124
20.03.2015, 11:54     Блок try catch жрет память #20
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
ели исключение не обработать, а оно не обрабатывается т.к нет e->Delete то и будет течь.
К сожалению, ты ответил на тему 3х летней давности. Я написал в ней же, у меня схожая проблема, но никого new в try нет. Никакой динамики в икле нет, а память уходит... Мой код на пару сообщений выше
Yandex
Объявления
20.03.2015, 11:54     Блок try catch жрет память
Ответ Создать тему
Опции темы

Текущее время: 05:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru