Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> освободится ли память? try... catch 
V
    Опции темы
ksili
Дата 16.3.2009, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



освободится ли память в такой конструкции, если между new и delete произошло исключение и управление попало в catch?
Код

....
try
    {
    char* data = new char[len];
    ....
    delete [] data;
    }
catch(...)   
    {
    ....
    }



--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
azesmcar
Дата 16.3.2009, 08:30 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата

освободится ли память в такой конструкции, если между new и delete произошло исключение и управление попало в catch?


нет, если будет брошено исключение, управление не дойдет до delete а сразу перейдет к блоку catch.

более того, если быть педантичным
Код

char* data = new char[len];


не гарантирует безопасность исключений. В С++ оператор new может генерировать исключения. Если использовать
Код

char* data = new(std::nothrow) char[10];


тогда оператор new вернет NULL. Но это так smile не думаю что это стоит проверять..так и так программа продолжать свою работу вряд ли сможет после того как уже не осталось памяти..хотя бывают и специфичные случаи.

Код

char* data = new char[len];
try
    {
    ....
    }
catch(...)   
    {
    ....
    }
delete [] data;

пиши так (если не собираешся делать rethrow в блоке catch

или
Код

try
{
   char* data = new char[len];
   try
       {
       ....
       }
   catch(...)   
       {
       ....
       }
   delete [] data;
} catch (std::bad_alloc& e) {
   //пытаемся красиво убить программу чтоб не мучалась  :smile 
}


хотя такие исключения как bad_alloc лучше перехватывать во входной точке.

Это сообщение отредактировал(а) azesmcar - 16.3.2009, 08:39
PM   Вверх
ksili
Дата 16.3.2009, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



azesmcar, спасибо за ответ. 

Т.к. у меня rethrow в блоке catch. Я сделал так:
Код

char* data;
try
    {
    data = new char[len];
    
    ....
    delete [] data;
    data = NULL;
    }
catch(...)   
    {
    ....
    if(data) delete [] data;
    throw CServerRequestException();
    }



--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
azesmcar
Дата 16.3.2009, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Код

    if(data) delete [] data;


лишняя проверка. инициализируй
Код

char* data = 0;


и удаляй спокойно, в С++ удаление нулевых указателей - вполне нормально
Код

char* data = NULL;
try
    {
    data = new char[len];
    
    ....
    delete [] data;
    data = NULL;
    }
catch(...)   
    {
    ....
    delete [] data;
    throw CServerRequestException();
    }

PM   Вверх
Lazin
Дата 16.3.2009, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



azesmcar, какой плохой совет smile 
во первых, не стоит использовать catch(...) без catch(const std::exception&) так как теряется контекст в котором произошла ошибка
во второых, лучше использовать идиому RAII, например использовать смарт поинтер

Код

try
{
    boost::scoped_array<char> data( new char[len]);
    ...

catch (const std::exception& e)
{
    ....обработка исключения
}
catch (...)
{
    //аварийное завершение
    --запись в лог файл создание дампа приложения
   _exit(-1);
}

PM MAIL Skype GTalk   Вверх
azesmcar
Дата 16.3.2009, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата

azesmcar, какой плохой совет smile 
во первых, не стоит использовать catch(...) без catch(const std::exception&) так как теряется контекст в котором произошла ошибка
во второых, лучше использовать идиому RAII, например использовать смарт поинтер


во первых
catch(...) писал не я, и я не думал что тут имеется ввиду перехват всех исключений. Человек чтобы не писать все, просто написал три точки.
во вторых
Цитата

во второых, лучше использовать идиому RAII, например использовать смарт поинтер

есть множество решений. А бы не стал использовать смарт поинтер, так как - стандартно такого смарт поинтера в С++ нет, а писать его для того чтобы не писать один лишний delete я бы тоже не стал.

Добавлено через 1 минуту и 37 секунд
и причем тут буст??? мы говорим о С++? в С++ нет такого класса как
Цитата

boost::scoped_array<char> data( new char[len]);


Добавлено через 3 минуты и 30 секунд
а вообще catch(...) не хорошо. Это можно поставить как дополнительную проверку во входной точке после
catch (std::exception& e)
PM   Вверх
Lazin
Дата 16.3.2009, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(azesmcar @  16.3.2009,  09:17 Найти цитируемый пост)
есть множество решений. А бы не стал использовать смарт поинтер, так как - стандартно такого смарт поинтера в С++ нет, а писать его для того чтобы не писать один лишний delete я бы тоже не ста

scoped_ptr в TR1
к тому-же, писать delete вручную можно, но это приводит к туче boilerplate кода
PM MAIL Skype GTalk   Вверх
azesmcar
Дата 16.3.2009, 09:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата

scoped_ptr в TR1


нет такого класса.  smile

Добавлено через 2 минуты и 12 секунд
Цитата

к тому-же, писать delete вручную можно, но это приводит к туче boilerplate кода 


зависит от того сколько раз придется это писать...конкретно в примере недостаточно информации чтобы посоветовать использовать smart pointer (по моему)
PM   Вверх
Lazin
Дата 16.3.2009, 09:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



действительно нет, зато есть в TR2 и в boost, в общем это не оправдание)
PM MAIL Skype GTalk   Вверх
ksili
Дата 16.3.2009, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Я ищу и исправляю места, где могли бы быть утечки, в большом проекте, написанном не мной. Так что переписывать на smart pointer'ы я не буду. Ограничусь тем, что здесь написал и добавлением логгирования в catch(..)       
там действительно троеточие!


--------------------
Ничто так не развивает аналитическое мышление, как отладка сложной программы без возможности пошагового выполнения (с)
PM MAIL   Вверх
azesmcar
Дата 16.3.2009, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата

действительно нет, зато есть в TR2 и в boost, в общем это не оправдание) 


кому??? с чего ты взял что я оправдываюсь и вообще мне это надо? и перед кем? У меня дома тоже полно классов написано...давайте о них поговорим. Если речь идет о С++ - тогда решаем проблему средствами С++, меня лично не устроил бы ответ "скачай буст и используй там один класс". Я не собираюсь качать буст ради одного класса который я буду использовать один раз в своей программе. Я согласен что как вариант ты мог предложить смарт поинтер, но это никак не влияет мой ответ. Лично я сделал бы так, еслиб использоват больше одного раза, написал бы свой смарт поинтер. Но контекст задачи мне не известен

Добавлено через 1 минуту и 26 секунд
Цитата

Я ищу и исправляю места, где могли бы быть утечки, в большом проекте, написанном не мной. Так что переписывать на smart pointer'ы я не буду. Ограничусь тем, что здесь написал и добавлением логгирования в catch(..)       


Bounds Checker пробовал?
PM   Вверх
mes
Дата 16.3.2009, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



а чем std::auto_ptr для текущего примера тс не подходит ?


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 16.3.2009, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата

а чем std::auto_ptr для текущего примера тс не подходит ? 


auto_ptr использует оператор delete а не delete []
Код

    ~auto_ptr()
        {    // destroy the object
        if (_Myptr != 0)
            delete _Myptr;
        }

PM   Вверх
Lazin
Дата 16.3.2009, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



по твоему писать 
Код

try
{
   data = new char[len];
   ...
   delete data;
   data = 0;
}
catch(...)
{
   if (data) delete data;
   data = 0;
}

есть хорошо?
намного чище на мой взгляд
Код

try
{
    boost::scoped_array data(new char[len]);
}
catch(...)
{
   //здесь только обработка ошибки, cleanup происходит автоматичксски
}

ну а если у тебя в ф-ии создаются динамчески несколько объектов?
Цитата(azesmcar @  16.3.2009,  09:34 Найти цитируемый пост)
Если речь идет о С++ - тогда решаем проблему средствами С++, меня лично не устроил бы ответ "скачай буст и используй там один класс". Я не собираюсь качать буст ради одного класса который я буду использовать один раз в своей программе.

boost smart_ptr - header only библиотека, и ничего за собой не тянет, к тому-же я не думаю что ты сможешь написать свой смарт поинтер, аналогичный по реализации boost::shared_ptr =)

Цитата(azesmcar @  16.3.2009,  09:34 Найти цитируемый пост)
кому??? с чего ты взял что я оправдываюсь и вообще мне это надо? и перед кем?

спокойно, дышим глубже ))
PM MAIL Skype GTalk   Вверх
azesmcar
Дата 16.3.2009, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата

есть хорошо?


речь не о том - хорошо это или плохо. а о том что вопрос не был
Цитата

как сделать этот код лучше


а о том что вопрос был
Цитата

освободится ли память в такой конструкции, если между new и delete произошло исключение и управление попало в catch?


я лишь отвечал как сделать так чтобы не было утечки памяти, никто не спрашивал хорошо ли писать catch(...). 
Цитата

намного чище на мой взгляд


я не спорю что это так. Но, к коду добавляется дополнительный файл, в итоге мы получаем где-то 50 строк в отдельном файле, и избавляемся от 3х строк в одном. Мне кажется что смысл использования смарт поинтера в данной задаче определяется множеством факторов о которых нам не известно, поэтому сказать однозначно - которое решение лучше я не могу. Я предложил одно, ты предлагай другое..а уж тот кому виден весь код решит которое из них для него более приемлемо.

Цитата

спокойно, дышим глубже )) 


я спокоен как слон. Просто не люблю слова оправдания - я никогда и ни перед кем не оправдывался и не собираюсь этого делать, если я не прав - извинюсь, если меня неверно поняли - обясню еще раз..но не буду оправдыватся..
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




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


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

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