Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564

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

17.01.2015, 10:42. Показов 23657. Ответов 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
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 05:37  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от hoggy Посмотреть сообщение
обычно случаются
вот и меня причислили символично в 2015 году)
Цитата Сообщение от hoggy Посмотреть сообщение
И из-за отсутствующих ловушек, процесс просто ляжет, как это проиллюстрированно в примере выше.
Ещё на первой странице сказали что использование nothrow даст моей переменной результат NULL, теперь вы говорите что не то что не даст, а даже не дойдёт до проверки... кому верить?.. (и ещё меня бараном символично обозвали, когда сами друг другу противоречите по логике)
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
19.01.2015, 06:06
Цитата Сообщение от Izual Посмотреть сообщение
Ещё на первой странице сказали что использование nothrow даст моей переменной результат NULL
operator new вернет nullptr. Если же память выделится, то в ход пойдут конструкторы из которых может вылететь исключение. new-expression почистит что должен и пробросит это исключение дальше - Проверка выделения памяти указателей через оператор new.
Не путайте new-expression и operator new.

std::nothrow просто приведет к вызову внутри new-expression соответствующей перегруженной функции:
C++
1
2
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
void* operator new[] (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
А после успешного выделения памяти начнут свою деятельность конструкторы объектов, со всеми вытекающими.

Вообще, всякие параметры, типа std::nothrow влияют только на выбор необходимого оператора:
5.3.4/11
The new-placement syntax is used to supply additional arguments to an allocation function. If used, overload resolution is performed on a function call created by assembling an argument list consisting of the amount of space requested (the first argument) and the expressions in the new-placement part of the new-expression (the second and succeeding arguments). The first of these arguments has type std::size_t and the remaining arguments have the corresponding types of the expressions in the new-placement.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <new>
     
struct M{};
     
void * operator new (std::size_t size, const M & ) noexcept
{
    std::cout << "call operator new" << std::endl ;
    return nullptr ;
}
     
     
int main() {
    int * p = new (M()) int() ;
}
http://ideone.com/8Y5pIW

Цитата Сообщение от Izual Посмотреть сообщение
когда сами друг другу противоречите по логике
ситуацию с вылетом исключения из конструктора уже обсудили. Собственно, вот основные выводы:
Цитата Сообщение от hoggy Посмотреть сообщение
А обеспечить 100% гарантию что из конструкторов не полетит - невозможно.
Это - исключительно ручная работа программиста. Все на его совести и усмотрении.
Таким образом, сама по себе возможность использования new(std::nothrow) несколько сомнительная.
Гарантий безопасности относительно исключений никаких не дает.
Но без этих гарантий, само использование - не безопасно.
Цитата Сообщение от Izual Посмотреть сообщение
и ещё меня бараном символично обозвали
Да никто Вас не обзывал. Плюсы не тот язык, который можно понять "налету"
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
19.01.2015, 07:14
Цитата Сообщение от Izual Посмотреть сообщение
Зря админ переместил тему в раздел для нубов, тут вполне серьёзный и сложный вопрос обсуждается
Семантика оператора new разжевывается в любой книжке по С++. Этой темы вообще не должно было бы быть, но видимо чукча не читатель, чукча писатель, лол.
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 07:19  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
Собственно, вот основные выводы
Я для чего делал топик? - Чтоб найти выход, вы же мне показываете то что "выхода нет" своим выводом.
Не ужели сложно написать исходя из моего примера первого поста так как будет правильно, если вообще может быть правильно, в чём я уже вообще не уверен...(из поста в пост один человек противоречит другому, заганяя меня, новичка в таких сложных тонкостях, в большее недопонимание что вообще тут происходит)
Цитата Сообщение от Croessmah Посмотреть сообщение
никто Вас не обзывал
Суть не в этом, а в том что вы из за своих противоречий (профессионалы ёпрст) не можете написать как надо, а сливаете всё в русло, где якобы я и виноват ещё...
Я вот не понимаю, вы больше 10 лет потратили на изучение подобных вопросов, и у кого то есть правильный ответ, но никто не делится... один поёт про одно, второй про другое... а мне значит сидеть и биться головой об стену и гадать кто же тут прав, а кто нет...

Добавлено через 2 минуты
Цитата Сообщение от Voivoid Посмотреть сообщение
разжевывается в любой книжке по С++
Ну ты же не чукча, напиши как будет правильно сделать.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
19.01.2015, 07:29
Цитата Сообщение от Izual Посмотреть сообщение
Ну ты же не чукча, напиши как будет правильно сделать.
Тебе правильнее будет писать на C
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 08:16  [ТС]
Цитата Сообщение от Voivoid Посмотреть сообщение
Тебе правильнее будет писать на C
Напиши правильно на С. Или ты только говорить умееш?.. Ну вот и сразу видно что ты из себя представляеш.
0
 Аватар для iRomul
163 / 104 / 14
Регистрация: 17.10.2012
Сообщений: 488
19.01.2015, 08:30
Оно?
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
#include <iostream>
#include <limits.h>
using namespace std;
 
struct type_t {
    int a;
    int b;
};
 
int main() {
    
    const int x(5000), y(5000), z(5000);
    
    type_t*** a;
    
    /* L1 Alloc */
    a = new(nothrow) type_t** [x];
    if( a == nullptr ) cerr << "Error at L1!" << endl;
    
    /* L2 Alloc */
    for( int i = 0; i < x; i++) {
        a[i] = new(nothrow) type_t* [y];
        if( a[i] == nullptr ) {
            cout << "Error at L2!" << endl;
            abort();
        }
    }
    
    /* L3 Alloc */
    for( int i = 0; i < x; i++) {
        for( int j = 0; j < y; j++) {
            a[i][j] = new(nothrow) type_t [z];
            if( a[i][j] == nullptr ) {
                cout << "Error at L3!" << endl;
                abort();
            }
        }
    }
    
    return 0;
}
Пример возникновения ошибки
1
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 08:36  [ТС]
Цитата Сообщение от iRomul Посмотреть сообщение
Оно?
Вопрос не по адресу, я как раз таки спрашиваю как надо чтоб не было ошибок... на взгляд очень красиво, но правильно или нет я не знаю..
0
 Аватар для iRomul
163 / 104 / 14
Регистрация: 17.10.2012
Сообщений: 488
19.01.2015, 08:38
Izual, зайдите по ссылки и сами посмотрите.
0
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
19.01.2015, 09:33
Цитата Сообщение от Izual Посмотреть сообщение
Напиши правильно на С
Не, я на C не пишу, только на C++. Это надо у местных C'шников спрашивать
0
 Аватар для saden
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
19.01.2015, 09:54
Izual, с таким предвосхищением ошибок перед каждой программной инструкцией надо ставить проверку, что программа еще работает, состояние памяти, отведенной для проги не изменилось, контрольные суммы будущей операции валидны. А после операции проверять все то же самое + погоду на Марсе
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 11:10  [ТС]
Цитата Сообщение от saden Посмотреть сообщение
с таким предвосхищением ошибок перед каждой программной инструкцией надо ставить проверку
Не страшно, я платформу пишу, автоматический GetLastError будет после каждой вызванной апи функции. Если измерение погоды на марсе было бы апи функцией, то и она бы проверялась, если бы использовалась.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
19.01.2015, 12:10
Цитата Сообщение от Izual Посмотреть сообщение
Я для чего делал топик? - Чтоб найти выход, вы же мне показываете то что "выхода нет" своим выводом.
В начале топика приводился new не вызывающий конструкторов. Вот это собственно и выход:
1) Не использовать конструкторы и функции плюющиеся исключениями.
2) Тщательно проверять что конструктор и используемые функции не будут плеваться исключениями. То есть, отказаться от минимум std::string, std::map, etc (могут выкинуть исключение "памяти мало").
0
 Аватар для saden
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
19.01.2015, 12:32
Цитата Сообщение от Izual Посмотреть сообщение
Не страшно, я платформу пишу
Тогда от new лучше отказаться и вернуться к malloc или вообще к инструкциям ассемблера.
0
 Аватар для Izual
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 12:37  [ТС]
Цитата Сообщение от Renji Посмотреть сообщение
конструкторы и функции плюющиеся исключениями
Так если я использую new[], и выделяю память большего размера нежели есть в наличии, то будет как раз это исключение... ну это я говорю основываясь на том что было описано выше в постах.
Цитата Сообщение от Renji Посмотреть сообщение
проверять что конструктор и используемые функции не будут плеваться исключениями
Как\где их все узнать?..

Теперь по примеру который показал iRomul - а если какая то другая ошибка появится?..
0
 Аватар для saden
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
19.01.2015, 12:44
Цитата Сообщение от Izual Посмотреть сообщение
Так если я использую new[], и выделяю память большего размера нежели есть в наличии
В защищенном режиме процессора на каждый процесс выделяется 4 Гб. Если не влазит в реальную оперативку, сбрасывается на подкачку.
Если Вам нужны приложения с возможным выходом за 4 Гб - нужно самостоятельно контроллировать сброс на диск. Если не нужны - доверьтесь new
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
19.01.2015, 12:49
Цитата Сообщение от Izual Посмотреть сообщение
Так если я использую new[], и выделяю память большего размера нежели есть в наличии, то будет как раз это исключение... ну это я говорю основываясь на том что было описано выше в постах.
Не будет. new работает в два этапа.
1) new выделяется память. Здесь можно проконтролировать кинет исключение или просто вернет nullptr.
2) new пинает конструктор объекта. А вот за происходящее внутри конструктора он никакой ответственности не несет. Оттуда вполне может прилететь исключение.
Цитата Сообщение от Izual Посмотреть сообщение
Как\где их все узнать?..
Порыть доки на www.cplusplus.com на тему "No-throw guarantee". Если все внешние функции с No-throw guarantee, все ваши функции не содержат ни одного throw и нет источника аппаратных исключений (деление на ноль, например), то проблем быть не должно.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.01.2015, 13:34
Цитата Сообщение от Izual Посмотреть сообщение
Ещё на первой странице сказали что использование nothrow даст моей переменной результат NULL, теперь вы говорите что не то что не даст, а даже не дойдёт до проверки... кому верить?..
Нужно не верить, а знать.

Для этого:
1. Я оставил ссылку на онлайн компилятор с демонстрацией кода в работе
2. Оставил рекомендацию взять в руки любой букварь для самых маленьких, раздел "работа с исключениями".
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.01.2015, 13:34

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

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

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

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

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


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

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

Новые блоги и статьи
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru