Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.66/119: Рейтинг темы: голосов - 119, средняя оценка - 4.66
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564

Проверка выделения памяти указателей через оператор new

17.01.2015, 10:42. Показов 23500. Ответов 77
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
И так есть некая структура, экземпляр которой определён как:
C++
1
var ***v;
Изначально заполняю экземпляр:
C++
1
2
3
4
5
6
7
8
9
v = new var**[1]; // создание 0-матрицы
if (v == NULL) // проверка выделения памяти для матрицы
    return -1;
v[0] = new var*[1]; // 0-массив
if (v == NULL)
    return -2;
v[0][0] = new var[3]; // 3 переменные
if (v == NULL)
    return -3;
В общем вопрос по двум проверкам (там где return -2 и -3), я честно говоря не понимаю как правильно написать условие проверки, т.е. явно что проверка "if (v == NULL)" не правильна, как сделать правильно?
Предполагаю что:
C++
1
2
3
4
5
6
v[0] = new var*[1]; // 0-массив
if (v[0] == NULL)
    return -2;
v[0][0] = new var[3]; // 3 переменные
if (v[0][0] == NULL)
    return -3;
Но мне кажется это не правильным, помогите поправить..
П.С. В дальнейшем естественно кол-во массивов и матриц будет больше 1, потому у меня сейчас сомнения того как правильно написать цикл проверки.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.01.2015, 10:42
Ответы с готовыми решениями:

Почему обращение к методам осуществляется через оператор прямого доступа, а не через оператор указателей->?
#include <iostream> using namespace std; class random { public: void Set(int b){a=b;} int Get(){return a;} private: ...

Вопрос по поводу динамического выделения памяти и указателей
void buildArray(int *arr,int lenght) { int i; arr = (int*)malloc(lenght * sizeof(int)); arr = 1; arr = 2; arr = 3; ...

Передача массива указателей в функцию для выделения памяти
Есть функция, в которую передаются массивы указателей, для выделения памяти. void str_malloc(char** &strBol,char**...

77
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.01.2015, 00:55
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Croessmah Посмотреть сообщение
5.3.4/18
Спасибо, я уже понял, new(std::nothrow) ортогонально исключениям,
которые могут выбросить конструкторы.

И что сам по себе std::nothrow не имеет никакого отношения к чему то подобному спецификатору noexcept.

Цитата Сообщение от Nick Alte Посмотреть сообщение
Зависит от конструируемых объектов.
Вы не поняли. Я имел ввиду гарантии.
Ну то есть, eсли использовать ловушку, то это превентивно 100% гарантия безопасной с точки зрения исключений работа. Потому что здесь нет человеческого фактора.

Если не использовать ловушки, то вот тогда зависит от конкретных конструкторов создаваемых объектов.

Но ведь получается, что использовать new(std::nothrow) имеет смысл только если точно известно,
что конструкторы так же не будут кидать исключений.

А обеспечить 100% гарантию что из конструкторов не полетит - невозможно.
Это - исключительно ручная работа программиста. Все на его совести и усмотрении.

Таким образом, сама по себе возможность использования new(std::nothrow) несколько сомнительная.
Гарантий безопасности относительно исключений никаких не дает.
Но без этих гарантий, само использование - не безопасно.

По сути, получаем "мину замедленного действия".
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
18.01.2015, 01:08
Цитата Сообщение от hoggy Посмотреть сообщение
А обеспечить 100% гарантию что из конструкторов не полетит - невозможно.
Это - исключительно ручная работа программиста. Все на его совести и усмотрении.
Да, например,
C++
1
new (std::nothrow) std::locale("Russian");
приведет к вылету исключения std::runtime_error на компиляторе MinGW в винде(во всяком случае пока он не может ставить не стандартные локали)
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.01.2015, 05:30
Цитата Сообщение от Croessmah Посмотреть сообщение
приведет к вылету исключения std::runtime_error на компиляторе MinGW в винде
Получается что из внутреннего блока try выйдет, а исключение кинет уже в каких-то действиях перед возвратом?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
18.01.2015, 05:31
Цитата Сообщение от hoggy Посмотреть сообщение
По сути, получаем "мину замедленного действия".
Это просто legacy-заплатка. Т.к. в достандартном С++ new как раз возвращал ноль в случае неудачи выделения памяти.
1
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.01.2015, 06:43  [ТС]
И самое главное, что на популярных сайтах даже не объясняется почему и в каких ситуациях может вылезти ошибка этого bad_alloc.. Вот потом спрашивается как научиться чисто программировать, если надо 7 потов излить чтоб хотя бы пресловутый New правильно использовать.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
18.01.2015, 09:01
Цитата Сообщение от Izual Посмотреть сообщение
и по логике почему бы просто не прервать операцию выделения памяти и просто c NULL сравнить
Потому что ошибок может произойти 100500 и каждую отдельно обрабатывать в лом.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void some_large_function()
{
    //здесь может произойти 100500 разнообразных ошибок
    //память кончилась, файл не открылся, на Марсе песчаные бури, etc
}
int main()
{
    while(true)
    {
        try
        {
            some_large_function();
            break;
        }
        catch(...)
        {
            //что-то сбойнуло, перезапускаем
            cout<<"наша песня хороша, начинай сначала"<<endl;
        }
    }
}
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.01.2015, 09:23  [ТС]
Цитата Сообщение от Renji Посмотреть сообщение
ошибок может произойти 100500
Какие 100500?.. Опретор new отвечает за выделение памяти и только.
Какие по логике могут произойти ошибки:
1. Нехватка памяти.
2. Уже выделена память для этого экземпляра, повторно естественно нельзя.
А больше я даже придумать не могу...
А если горе программист ленится делать проверки операций, которые он вызывает, то это лишь говорит о его не компитентности.
Даже я, не особо шарющий не скуплюсь на проверки (возможно не всегда, но это лишь из за отсутсвия инфы, и как раз такой случай здесь - нет информации о причинах появления ошибок).

П.С. Зря админ переместил тему в раздел для нубов, тут вполне серьёзный и сложный вопрос обсуждается, а из за того что тема в клоповнике - будут как раз заходить такие вот горе программисты, которым "в лом". (ну раз в лом, то "не умееш с*ать - не мучай жопу", если делать то правильно, а иначе зачем вообще делать)
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
18.01.2015, 09:31
Цитата Сообщение от Izual Посмотреть сообщение
Какие 100500?.. Опретор new отвечает за выделение памяти и только.
1) Нет памяти.
2) Нет подключения к сети.
3) Из сети пришла какая-то фигня, которую парсер переварить не может.
4) Еще какая-то фигня, после которой можно только аварийно завершить процедуру.
Я же специально написал "some_large_function" подразумевая что там сложный код запихан, а не только new. И 100500 раз прописывать код аварийного завершения в лом. Для этого компилятор есть.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
18.01.2015, 09:42
Цитата Сообщение от Izual Посмотреть сообщение
Опретор new отвечает за выделение памяти и только.
оператор - да, а new-expression еще и вызывает соответствующие конструкторы
Цитата Сообщение от Izual Посмотреть сообщение
Какие по логике могут произойти ошибки:
уже написали выше - может вылететь исключение в конструкторе.
Цитата Сообщение от Izual Посмотреть сообщение
Зря админ переместил тему в раздел для нубов, тут вполне серьёзный и сложный вопрос обсуждается
в каком месте?
Цитата Сообщение от Izual Посмотреть сообщение
А если горе программист ленится делать проверки операций, которые он вызывает, то это лишь говорит о его не компитентности.
Причем тут проверки? Исключения позволяют отделить код основного алгоритма от кода обработки ошибок, а так же без лишних проблем пробросить исключение дальше по стеку.

Я так понимаю, Вам просто не понятно для чего нужны исключения и как их использовать? В ином случае, уже я не понимаю, что мы тут обсуждаем.
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.01.2015, 10:00  [ТС]
Renji, вася, тут тема про оператор New. Если тебе заняться нечем - не мешай другим, не разводи лишний балаган не по теме.

Цитата Сообщение от Croessmah Посмотреть сообщение
уже написали выше - может вылететь исключение в конструкторе.
Вопрос был о причинах возникновения.
Цитата Сообщение от Croessmah Посмотреть сообщение
отделить код основного алгоритма от кода обработки ошибок
GetLastError пихать после каждой процедуры - очень хорошо на мой взгляд, особенно если есть обработчик этих ошибок, ладно, можно без устранения - это трудоёмко, но хотя бы чтоб если уж какие ошибки и возникают - видеть их причину.(например по номеру ошибки от GLE выводить текст, который описан на MSDN и вести лог)
*Но ты так написал, что непонятна суть фразы, потому я ответил так же разплывчато.

Цитата Сообщение от Croessmah Посмотреть сообщение
уже я не понимаю
А ты с самого начала не понял, я ищу истоки ошибок, и уже не раз сказал эту фразу. Ну видимо "будете смотреть да не увидите".
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
18.01.2015, 10:04
Цитата Сообщение от Izual Посмотреть сообщение
Renji, вася, тут тема про оператор New. Если тебе заняться нечем - не мешай другим, не разводи лишний балаган не по теме.
Обсуждаемые исключения изобретались не для случая "весь код состоит из одного оператора new, больше нигде ошибок приключиться не может, вложенных вызовов в природе тоже не бывает".
Цитата Сообщение от Izual Посмотреть сообщение
GetLastError пихать после каждой процедуры - очень хорошо на мой взгляд, особенно если есть обработчик этих ошибок, ладно, можно без устранения - это трудоёмко, но хотя бы чтоб если уж какие ошибки и возникают - видеть их причину.
C++
1
2
3
4
catch(const std::exception&error)
{
    cout<<error.what()<<endl;
}
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
18.01.2015, 10:16
Цитата Сообщение от Izual Посмотреть сообщение
GetLastError пихать после каждой процедуры - очень хорошо на мой взгляд
Это функция ОС, а не языка.
Цитата Сообщение от Izual Посмотреть сообщение
но хотя бы чтоб если уж какие ошибки и возникают - видеть их причину.
Никто не запрещает Вам перегрузить функцию operator new, в которой Вы можете сделать любые проверки на свой вкус и цвет.
Цитата Сообщение от Izual Посмотреть сообщение
я ищу истоки ошибок
Истоки - в операционной системе. Запросили память, нам её не дали, спросили почему, получили ответ, приняли решение что делать дальше.
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.01.2015, 10:22  [ТС]
Цитата Сообщение от Renji Посмотреть сообщение
исключения изобретались не для случая
Вот именно что ежели уж что то пошло не так, то надо ставить собственную проверку удачного завершения процедуры, а не ждать что манна небесная прольётся из компилятора и скажет "найн")))
Вообще спорить со мной безполезно, ты намекаеш на удобство, мол "нафига мне всё это контролить, если за меня это сделает кто то другой", а я считаю что такой подход делает программистов однокнопочными "юзверами", которые из за вот такого вот угрюмого стиля\подхода совсем перейдут на шаблонный стиль. (С\С++ языки высокого уровня, не надо их превращять в огрызки)

Добавлено через 5 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
перегрузить функцию operator new
погуглю, мб что найдётся... через 100 лет)))
Цитата Сообщение от Croessmah Посмотреть сообщение
Запросили память, нам её не дали, спросили почему.
Ну и вытекает вопрос как это сделать... О том вообще и речь была, чтоб поправить код и дать комментарий.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
18.01.2015, 10:23
Цитата Сообщение от Izual Посмотреть сообщение
Вот именно что ежели уж что то пошло не так, то надо ставить собственную проверку удачного завершения процедуры
Если в этой проверке будет хоть что-то помимо цепочки return error_code, так ради бога. А так - те же яйца, профиль сбоку. Только писанины больше.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
18.01.2015, 10:31
Цитата Сообщение от Izual Посмотреть сообщение
мол "нафига мне всё это контролить, если за меня это сделает кто то другой"
не в этом суть. Простой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
//...
public:
   A operator/ ( int x ) const
   {
      if ( x != 0 )
         return A(this->b/x) ;
      //Как уведомите вызывающий код о том, что произошло деление на ноль?
   }
//...
} ;
Добавлено через 5 минут
Цитата Сообщение от Izual Посмотреть сообщение
Ну и вытекает вопрос как это сделать... О том вообще и речь была, чтоб поправить код и дать комментарий.
Можете выделять память используя системный API (например, функцию HeapAlloc в windows). Ну и проверять ошибки её выполнения.
Цитата Сообщение от Izual Посмотреть сообщение
погуглю, мб что найдётся... через 100 лет)))
http://www.cap-design.ru/ccc/glav13.htm
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.01.2015, 10:37  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
Как уведомите уровень выше, что произошло деление на ноль?
Не пользуюсь такими конструкциями именно из за таких вот вытекающих ошибок. А если уж и надо проверку, то прежде чем вызывать, надо заранее проверить этот х на "валидность".
Цитата Сообщение от Renji Посмотреть сообщение
те же яйца, профиль сбоку
Всё дело в удобстве чтения кода, вот когда в программе куча непонятных алгоритмов и опреторов, которыми всё усеяно, то только на понимание уйдёт кучу времени - легче один раз правильно и просто сделать, так же как и советские автомобили или автомат калашникова. (4 колеса, мотор, и всё разборное, на случай поломки можно прям на ходу подвязать подгузник и доехать до ближайшего населённого пункта. В отличии от европейского стиля, когда диод перегорел и машина просто остановилась в ку*ве кукуеве, и придётся заплатить 100500wmz за вызов эвакуатора - ну не для людей это сделано, я для прибыли..)
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.01.2015, 14:57
Цитата Сообщение от Izual Посмотреть сообщение
Вопрос был о причинах возникновения.
Все что угодно.
Вам стоит понять, что исключение может бросить не только new,
но и конструктор конструируемого класса,

Любая функция, которая была использована внутри этого конструктора.

У класса может оказаться мембер, который тоже при своем создании может бросить исключение.
В этом случае оно вылетит из конструктора агрегата ещё до того, как запустится конструктор этого агрегата.

Вы должны понять одну истину:
Вы пишите код, которые потенциально может отработать с ошибками.
Это - аксиома.
Если вы думаете, что ваш код безопасен и стабилен - вы заблуждаетесь.

Вы должны учитывать это, как аксиому: любой код, любая ветвь исполнения потенциально может завершится программным сбоем.

Сбойный сектор на жестком диске, отказ железа, скачек напряжения в электрической розетке, или ошибки программных алгоритмов - все что угодно.

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

Но если вы хотите писать серьёзный отказоустойчивый софт, который должен быть безопасен
(например, вспомогательные системы управления пассажирским авиалайнером)

Вам стоит понять: система должна сохранять работоспособность вопреки.
Вы должны суметь перехватить и обработать любые "стрессовые" ситуации.

Более того, обработчик нештатных ситуаций пишится в условиях, когда изначально не известно, что за ошибка то может быть. Потому что ошибка может быть какая угодно, и всегда - неожиданная.
(все известные ошибки были отловлены ещё на этапе тестирования).

Для этого архитектура изначально проектируется так, что бы все узлы имели строгие гарантии безопасности.
Это означает, что компонент можно откатить к некому первоначальному состоянию без потери данных:

если ошибка - откатываем всю операцию назад. И пробуем заново. Ошибка редкая - второй раз может прокатить.

Либо так, что бы компоненты можно было полностью перезапустить.

При работе с ошибками важно выявить и обработать все известные ошибки.
Но это - лишь половина дела.

Но главное - сохранить жизнь приложению в условиях,
когда возникают не известные, не понятно из-за чего возникающие.

http://rextester.com/BQPZ66179

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//Title of this code
//Compiler Version 18.00.21005.1 for x86
 
#include <stdexcept>
#include <iostream>
#include <ctime>
 
using namespace std;
 
struct example
{
    ~example() 
    {
        cout<<"dtor\n";
        delete [] data; 
    }
    
    
    example(): data( new int[255] )   //<--- если полетит здесь, то утечек ресурсов не будет.
    {                              // Тем не менее, потенциальная дыра в безопасности.
        cout<<"ctor\n";
        
        static int seed(         //<--- гарантируется однократный вызов 
            ( srand(time(0)) ,0)  // при первом запуске конструктора  
        );
        (void)seed;
        
        const auto v = rand()%3;
        if(v==1)
            simulate_runtime_fault();
        else if(v==2)
            simulate_unkown_fault();
            
        
        
        
        // <--- ПОТЕНЦИАЛЬНАЯ УТЕЧКА РЕСУРСОВ.
        //       ИСПРАВИТЬ КОД!!!!
        
        //ИСТОРИЯ БОЛЕЗНИ:
        //объект, чей конструктор не был до конца завершен исчитается "недостроенным"
        //для недостроенных объектов диструктор вызван не будет.
        //следовательно никто не освободит память по указателю data
            
        //обратите внимание на количество конструкторов и количество диструкторов в консольном выводе.
        
        //ЛЕКАРСТВО:
        //1. Использовать RAII (отличный способ)
        //2. Ставить ловушки на всех местах потенциальных утечек (хороший способ)
        //3. Заложиться на то, что исключительных ситуаций не будет (говнокод)
    }
private:    
    static void simulate_runtime_fault()
    {
        throw ::std::runtime_error("simulation runtime fault");
    }
    static void simulate_unkown_fault()
    {
        throw ::std::string("simulation unkown fault");
    }
    
    int* data;
    
};
 
 
int main()
{
    
 
    std::cout << "Hello, world!\n";
    
    
    for(size_t n=0;n<10;++n)
    try{
        
        new(std::nothrow) example;
    }
    catch( const std::bad_alloc& e)
    {
        cout<<"Ошибка выделения памяти.\n";
        cout<<"MEMORY: "<<e.what()<<'\n';
        
        cout<<"Поиск захваченной памяти в пулах\n";
        cout<<"Дефрагментация пулов\n";
        cout<<"Успешное восстановление после паники\n";
    }
    catch( const std::exception& e )
    {
        cout<<"Известная ошибка: "<<e.what()<<'\n';
        cout<<"Успешное восстановление после паники\n";
    }
    catch( ... )
    {
        cout<<"Неопознанная ошибка. Перезапускаем модуль\n";
        cout<<"Успешное восстановление после паники\n";
    }
}

ЗЫ:

Механизм исключений позволяет отловить любые исключения в автоматическом режиме.
То есть, программисту можно не бояться, что он ничайно позабыл где-то, чего-то.

Проверка возвращаемых значений: кодов, либо на NULL такой автоматики не предоставляет.
Соответственно, код написанный в сишном стиле не даёт никаких гарантий стабильности.

Добавлено через 30 минут
зы: в приведенном выше коде используется new(std::nothrow)
И создается иллюзия, якобы исключение std::bad_alloc не случится.

Однако это не так: он может вылететь из конструктора:
C++
1
example(): data( new int[255] ) //<--- вот отсюда
1
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
18.01.2015, 18:50  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
конструктор конструируемого класса
Классная фраза, и только, как и всё что там с конструкторами.. (пока что тёмный лес для меня, да и не уверен что буду пользоваться не то что классами, даже конструкторами)
Цитата Сообщение от hoggy Посмотреть сообщение
Сбойный сектор на жестком диске, отказ железа, скачек напряжения в электрической розетке, или ошибки программных алгоритмов - все что угодно.
Вот это интересные предположения, особенно первые два, которые думаю можно как то проверить... алгоритмы - это уже собственно касяки программера будут, а с скачками напряжения - тут уж и кирпич может на голову упасть в любой день...
Цитата Сообщение от hoggy Посмотреть сообщение
простенькую лабуду
Я создаю программу для управы, видел программу которая работает с данными по воде (типа программа, которая работает через интернет), так там каждый раз как с ней работаеш - молиться надо чтоб до ввода всех данных ничего не заглючило, в масштабах вселенной это конешно лабуда, но для сотрудников управы раз в месяц работа с этой программой становится напряженней чем весь прошедший месяц, т.к. горе программисты сделали так, что нельзя сохранить пока всё не введёш, но пока всё введёш - с шансом 50\50 программа вылетает... видел уже столько раз это, что сделал вывод, что если уж делать дело, то максимально точно.. (либо уж делать хорошо, либо совсем не делать. конешно выше описанные проблемы железа и т.п. это очень редко, но! вот я себе представил, что если вдруг именно из за железа там вылезала ошибка, то хотелось бы как минимум узнать об этом, чтоб после возникновения 2ой такой же - сделать вывод и принять меры) *ну так навеяло* =)
Цитата Сообщение от hoggy Посмотреть сообщение
можно просто заново перезапустить
Систему автосэйва сделать с двойными бэкапами, вот об этом думаю в будущем.
Цитата Сообщение от hoggy Посмотреть сообщение
И пробуем заново.
Ну как бы я именно по этому и пытаюсь с NULL'ом всё сделать, т.к. предполагается алгоритм с повторным действием если результат NULL... (только не безконечный цикл, а опр. кол-во раз, например 3, и например по времени с остановкой в N геометрической прогрессии, если уж ни как - то ручной контроль..)
Цитата Сообщение от hoggy Посмотреть сообщение
главное - сохранить жизнь приложению
Ну на то и оператор нужен, чтоб ставить галочки в появляющихся окошках с вопросами о последующих действиях)) Автоматизация это конешно хорошо, но идеальной системы в ней добиться будет очень трудно, если вообще возможно... (вспомнил фразу из сериала сверхъестественное, где смерть говорит, что когда нибудь она пожнёт бога^^, вот вам и система)

ЗЫ, классный пример у вас кода, только мальца не понятно... при catch он опять попробует try чтоль?.. и так в безконечном цикле?..

2ЗЫ: эта конструкция try,catch,catch... мне напоминает switch с case, который на взгляд очень удобен, но на деле: 1. Его невозможно динамически применить(я идеалист, работаю только с динамикой). 2. Кажется что только на нужный case сработает (ну если его нет то в default), но на деле это тот же самый обычный цикл, который статично в порядке написания программером будет выполняться (условно от 0 до N+default[1])..

3ЗЫ: такое ощущение что этот try можно запихнуть куда угодно и где только можно использовать, но ведь с тем же успехом я и GetLastError (я думал что это чисто Си метод, но раз мне тут сказали что он от ОСи win, то ну ладно, не суть) могу пользоваться с теми же выводами ошибок. По сути же вы решаете проблему перезапуском микро алгоритма или макро, что в принципе можно сделать даже если результат операции будет NULL, в последовательности конешно менее удобной (придётся выполнить сначало микро откат, а потом уже макро, т.е. 2 отката, даже если проблема в 2-ом случае), но принцип останется тот же, даже возможно чуть удобнее, т.к. можно самому написать алгоритм откатов и т.п.
Цитата Сообщение от hoggy Посмотреть сообщение
создается иллюзия, якобы исключение std::bad_alloc не случится
Почему это иллюзия? Тут же сказали что если new выдал эту ошибку, то экземпляр просто останется NULL, что уже даст возможность отследить что это произошло, надо только проверку на это сделать, в общем то именно из за этого я и хотел именно с NULL сравнивать, чтоб не было никаких иллюзий и недопониманий, т.к. я себе могу представить что даже после 2 лет работы я знаю не больше 5% о языке, а тратить всю жизнь на изучение всех всех новшеств - ну глуповато, если можно пользоваться старыми проверенными методами.
0
31 / 31 / 6
Регистрация: 23.10.2014
Сообщений: 107
18.01.2015, 22:15
Цитата Сообщение от Izual Посмотреть сообщение
при catch он опять попробует try чтоль?.. и так в безконечном цикле?
Где ж вы тут цикл бесконечный увидали? Десять итераций, на каждой итерации, пытаемся выделить память под объект класса example. Исключения отлавливаем.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for (size_t n = 0; n < 10; ++n) {
    try{
        new (std::nothrow) example;
    }
    catch( const std::bad_alloc& e )
    {
        // ...
    }
    catch( const std::exception& e )
    {
        // ...
    }
    catch( ... )
    {
        // ...
    }
}
Цитата Сообщение от Izual Посмотреть сообщение
Тут же сказали что если new выдал эту ошибку, то экземпляр просто останется NULL, что уже даст возможность отследить что это произошло
Вам дали пример, но вы всё равно не поняли.
Вот пример простой. Скомпилируйте и запустите.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <new>
 
class T {
  public:
    T()
    {
      throw 0; // предположим что тут бла-бла-бла сложные действия
    }
}; // class thrower
 
int main(int, char * []) {
  T * p = new (std::nothrow) T;
 
  if (p == NULL)
    std::cout << "new failed\n";
  else
    std::cout << "new succeed\n";
}
Цитата Сообщение от Izual Посмотреть сообщение
тратить всю жизнь на изучение всех всех новшеств - ну глуповато, если можно пользоваться старыми проверенными методами

Не по теме:

Перфокарты наше всё?


Вы же язык не знаете, о каких новшествах может идти речь? И чего такого плохого в обучении? Не хотите пользоваться средствами C++? Пользуйтесь чистым C, в чем проблема-то?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.01.2015, 23:07
Лучший ответ Сообщение было отмечено DrOffset как решение

Решение

Цитата Сообщение от Izual Посмотреть сообщение
Почему это иллюзия? Тут же сказали что если new выдал эту ошибку, то экземпляр просто останется NULL
Вы так ничего и не поняли.
Если полетит исключение (любое, не важно откуда, не важно почему),
то никакие ваши проверки на NULL уже просто не отработают.

Код с ними и после них просто не выполнится.

http://rextester.com/QGYKX26296

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
//Title of this code
//g++  4.8.2
 
#include <iostream>
 
struct example
{
    example()
    {
        throw ::std::bad_alloc(); //<--- симуляция сбоя
    }
};
 
int main()
{
    std::cout << "Hello, world!\n";
    
    auto* p = new(std::nothrow) example;
 
    //<---- до этой точки исполняющий процесс никогда не дойдет.
 
    if(p)                  
        std::cout << "success\n";
    else
        std::cout << "failed\n";
    
}

Error(s):
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc

Abort signal from abort(3) (SIGABRT)
Я попробую ещё раз пояснить этот момент:
C++
1
new(std::nothrow)
Предполагает, что вы не работаете с исключениями.
То бишь, вы используете сишную работу над ошибками.

Однако, такая конструкция вовсе не гарантирует вам, что исключений действительно не будет.

И из-за отсутствующих ловушек, процесс просто ляжет, как это проиллюстрированно в примере выше.

Что бы этого гарантированно не произошло, нужно ставить ловушки.
Но если вы ставите ловушки, то std::nothrow вам не нужен, потому что вы уже работаете с исключениями.

То, о чем вы пишите называется "си с классами" в лучшем случае.
Мысли аля "я не хочу использовать конструкторы/исключения/шаблоны/лямбды/etc" обычно случаются из-за банального не знания языка.
И это проходит по мере его освоения.

Добавлено через 5 минут
Цитата Сообщение от Izual Посмотреть сообщение
при catch он опять попробует try чтоль?.. и так в безконечном цикле?..
2ЗЫ: эта конструкция try,catch,catch... мне напоминает switch с case,
Не нужно гадать.
Возьмите в руки любую книжку "базовый курс с++".
Раздел "Обработка исключительных ситуаций".

Там все написано.

Цитата Сообщение от Izual Посмотреть сообщение
я идеалист, работаю только с динамикой
Вы работаете с с++ в данном случае.
А это - статический язык.

На с++ можно реализовать любую динамику, кроме рефлексивной.
Но для этого нужно сначала понять статику.

И тогда со временем придет понимание, что в основе любой динамики лежит статика.
Тогда можно будет изготавливать хорошие динамические решения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.01.2015, 23:07

Ввод/вывод двумерного массива с использованием указателей и выделения памяти
Доброго времени суток. Такая проблема. Нужно написать программу с использованием функций для ввода/вывода двумерного массива с...

Проверка выделения памяти
Была функция: struct TreeNode *insert(struct TreeNode* rootPtr, int data) { if (rootPtr == NULL) { rootPtr = (struct...

Проверка выделения памяти
Алгоритм верен, все работает. Хочу проверять работу с памятью. т.е. проверять, что память действительно выделилась/освободилась. С...

Проверка возраста через оператор switch
Дан возраст человека мужского пола в годах. Вывести на экран возрастную категорию: до года – «младенец», от года до 11 лет – «ребенок», от...

Выделение памяти для массива через оператор new
Вопрос знатокам, объявляю глобальный статистический указатель static myStrucType* mas; надо для динамического массива, потом выделяю ...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru