Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.75
bgm313
12 / 12 / 2
Регистрация: 27.07.2012
Сообщений: 208
#1

Динамическое выделение памяти - C++

28.08.2012, 14:49. Просмотров 1693. Ответов 7
Метки нет (Все метки)

Пусть есть класс с полем char *p. Если для поля p выделяется память динамически, как для массива и для самих объектов память выделяется тоже динамически в main. То где ловить исключения, которые могут быть связаны с выделением памяти: и в конструкторах и в основной программе или только в основной программе, а в конструкторах выбрасывать соотв.исключения?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.08.2012, 14:49
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Динамическое выделение памяти (C++):

Распределение памяти. Динамическое выделение памяти - C++
an-1 an-2 ... a2

Динамическое выделение памяти - C++
создать динамический масив, создать функцию, которая сумирует все елементы масива, и функцию, которая печатает содержимое масива и...

Динамическое выделение памяти - C++
Создайте динамический массив, хранящий в первой строке имя, а во второй - телефон. Организуйте поиск по имени и по номеру телефона и...

Динамическое выделение памяти - C++
У меня есть двумерный булевый квадратный массив. После запуска программы, я получаю переменную size, это то, сколько элементов должно быть...

Динамическое выделение памяти - C++
Имеется такая вот задача ! Нужно сделать что бы память выделялась динамически,а не на этапе компиляции!!! Какие будут предложения ??? ...

Динамическое выделение памяти - C++
Здраствуйте. Собственно сам код и вопрос: почему могу свободно выходить за границы массива? Для чего тогда размерность указывается......

7
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
28.08.2012, 15:00 #2
все зависит от целей вылавливания исключения.

вот код:
Foo* p = new Foo();

тут сперва выделяется память под объект типа Foo. Если не получилось, то летит исключение и до конструктора Foo дело не доходит. Если же все хорошо, то в выделеной памяти начинает конструироваться объект. В общем вызывается конструктор Foo. Внутри конструктора выполняется код, который бросает исключение (в том числе может бросится исключение о неудачном выделении памяти или хз что еще. все зависит от того, что именно происходит в конструкторе). Если это исключение покидает конструктор, то объект не создан до конца и деструктор для него не зовется. Эту ситуацию отлавливает код оператора new, освобождает выделенную память и пробрасывает исключение дальше. Если же икслючение ловится в теле конструктора и не копидает его, то объект вроде как сконструируется. Возможно у него будет невалидное состояние с точки зрения полозователей такого класса, но тем не менее это будет полностью сконструированный объект.
1
grizlik78
Эксперт С++
1966 / 1459 / 120
Регистрация: 29.05.2011
Сообщений: 3,018
28.08.2012, 15:02 #3
Это в большей степени зависит от логики самого конструктора. Если там можно продолжить создание объекта, несмотря на невозможность выделения памяти, то можно перехватить. Если требуется выполнить какие-то действия, связанные с неудачным выделением, то тоже придётся перехватывать (в конструкторе). Но в большинстве случаев можно в конструкторе ничего не делать, а обрабатывать в вызывающей функции или дальше.
Стоит рассмотреть, кстати, возможность замены int* на std::vector<int>. Если по-каким-то причинам это нежелательно, то следующие кандидаты на рассмотрение std::auto_ptr<int> и std::shared_ptr<int> (последний только для C++11, но есть аналог в boost).
1
bgm313
12 / 12 / 2
Регистрация: 27.07.2012
Сообщений: 208
28.08.2012, 15:15  [ТС] #4
Скажите, а как можно сделать так, чтобы при вызове конструктор и при неудачном выделение памяти для поля в конструкторе, происходил откат, т.е. объект разрушался. Может быть вызвать деструктор из конструктора?
0
grizlik78
Эксперт С++
1966 / 1459 / 120
Регистрация: 29.05.2011
Сообщений: 3,018
28.08.2012, 15:20 #5
Всё, что успело "сконструироваться" до возникновения исключения будет разрушено автоматически (главное, чтобы это исклчение хоть где-то в программе перехватывалось). Деструктор явно вызывать нельзя, так как созданные объекты будут разрушаться дважды, и даже созданные один раз тоже будут разрушаться. Так что либо не обрабатывать исключение в конструкторе, либо обработав прокинуть его дальше (это если надо разрушить объект).
1
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
28.08.2012, 15:21 #6
Ловить в конструкторе; удалять (тоже в конструкторе) всё, что построили до этого (но не более), и бросать дальше.

Не надо грузить вышележащий код, который вызвал этот самый конструктор Object, своими микропроблемами: "аааа, Object не может выделить память для своего третьего сверху приватного поля". Ему важна макропроблема: у него Object не создался. Что он будет делать, когда словит такое исключение? Объект инициализирован криво, так что деструктор может только усугубить ситуацию. Узнать и починить проблему внутри Object внешний код тоже не может. Так что уж лучше, когда Object() сам уберёт за собой и скажет наверх: "Мама, я облажался, но всё прибрал, можно сделать ещё попытку".
1
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
28.08.2012, 15:23 #7
никак. деструктор нельзя звать для неполностью сконструированного объекта.
откат делается за счет идиомы RAII (Resource allocation is initialization). Как уже сказали, мемберы, для которых выделяется память лучше заворачивать в смарт поинтеры. В этом случае все отработает как надо:

C++
1
2
3
4
5
6
7
8
9
10
11
12
class Foo
{
   std::auto_ptr<int> m_ptr1;
   std::auto_ptr<int> m_ptr2;
 
public:
   Foo()
     : m_ptr1(new int(1))
     , m_ptr2(new int(2)) // вот тут летит исключение
   {
   }
};
В такой ситуации объект m_ptr1 будет полностью сконструирован, а m_ptr2 - нет. Т.к. деструкторы зовутся для полностью сконструированных объектов а m_ptr1 - как раз такой объект, а не голый указатель, для него деструктор позовется несмотря на то, что деструктор класса Foo вызван не будет. Деструктор auto_ptr<T> как раз позовет delete для указателя, который хранится в этом смарт-поинтере
1
-=ЮрА=-
Заблокирован
Автор FAQ
28.08.2012, 15:23 #8
bgm313, исключения с выделением памяти - это bad_alloc делай вот такую обвёртку
C++
1
2
3
4
5
6
7
8
try
{
    int *ptr = new int[N];
}
catch(bad_alloc &e)
{
    cerr<<e.what()<<endl;
}
1
28.08.2012, 15:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2012, 15:23
Привет! Вот еще темы с ответами:

Динамическое выделение памяти - C++
Добрый день. Возник вопрос: Как мне узнать адрес последнего байта в выделенной памяти? Я выделил память (массив нулей и единиц): ...

Динамическое выделение памяти - C++
Добрый день! пытаюсь освоить С++ и дошёл до раздела динамического выделения памяти. Беру пример с сайта cppstudio.com всё работает ...

Динамическое выделение памяти - C++
Доброго времени суток. Пытаюсь разобраться с динамическим выделением память. Суть: Есть структура с двумя полями: 1. Указатель...

Динамическое выделение памяти - C++
Почему распечатка матрицы Matr1 в f2 дает матрицу из ед., а в f1 матрицу из нулей? Ведь адрес первого эл. массива Matr2 сохранен в...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

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