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

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

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

Author24 — интернет-сервис помощи студентам
И так есть некая структура, экземпляр которой определён как:
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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2015, 10:42
Ответы с готовыми решениями:

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

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

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

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

77
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 05:37  [ТС] 61
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от hoggy Посмотреть сообщение
обычно случаются
вот и меня причислили символично в 2015 году)
Цитата Сообщение от hoggy Посмотреть сообщение
И из-за отсутствующих ловушек, процесс просто ляжет, как это проиллюстрированно в примере выше.
Ещё на первой странице сказали что использование nothrow даст моей переменной результат NULL, теперь вы говорите что не то что не даст, а даже не дойдёт до проверки... кому верить?.. (и ещё меня бараном символично обозвали, когда сами друг другу противоречите по логике)
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
19.01.2015, 06:06 62
Цитата Сообщение от 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
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
19.01.2015, 07:14 63
Цитата Сообщение от Izual Посмотреть сообщение
Зря админ переместил тему в раздел для нубов, тут вполне серьёзный и сложный вопрос обсуждается
Семантика оператора new разжевывается в любой книжке по С++. Этой темы вообще не должно было бы быть, но видимо чукча не читатель, чукча писатель, лол.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 07:19  [ТС] 64
Цитата Сообщение от Croessmah Посмотреть сообщение
Собственно, вот основные выводы
Я для чего делал топик? - Чтоб найти выход, вы же мне показываете то что "выхода нет" своим выводом.
Не ужели сложно написать исходя из моего примера первого поста так как будет правильно, если вообще может быть правильно, в чём я уже вообще не уверен...(из поста в пост один человек противоречит другому, заганяя меня, новичка в таких сложных тонкостях, в большее недопонимание что вообще тут происходит)
Цитата Сообщение от Croessmah Посмотреть сообщение
никто Вас не обзывал
Суть не в этом, а в том что вы из за своих противоречий (профессионалы ёпрст) не можете написать как надо, а сливаете всё в русло, где якобы я и виноват ещё...
Я вот не понимаю, вы больше 10 лет потратили на изучение подобных вопросов, и у кого то есть правильный ответ, но никто не делится... один поёт про одно, второй про другое... а мне значит сидеть и биться головой об стену и гадать кто же тут прав, а кто нет...

Добавлено через 2 минуты
Цитата Сообщение от Voivoid Посмотреть сообщение
разжевывается в любой книжке по С++
Ну ты же не чукча, напиши как будет правильно сделать.
0
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
19.01.2015, 07:29 65
Цитата Сообщение от Izual Посмотреть сообщение
Ну ты же не чукча, напиши как будет правильно сделать.
Тебе правильнее будет писать на C
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 08:16  [ТС] 66
Цитата Сообщение от Voivoid Посмотреть сообщение
Тебе правильнее будет писать на C
Напиши правильно на С. Или ты только говорить умееш?.. Ну вот и сразу видно что ты из себя представляеш.
0
163 / 104 / 14
Регистрация: 17.10.2012
Сообщений: 488
19.01.2015, 08:30 67
Оно?
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
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 08:36  [ТС] 68
Цитата Сообщение от iRomul Посмотреть сообщение
Оно?
Вопрос не по адресу, я как раз таки спрашиваю как надо чтоб не было ошибок... на взгляд очень красиво, но правильно или нет я не знаю..
0
163 / 104 / 14
Регистрация: 17.10.2012
Сообщений: 488
19.01.2015, 08:38 69
Izual, зайдите по ссылки и сами посмотрите.
0
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
19.01.2015, 09:33 70
Цитата Сообщение от Izual Посмотреть сообщение
Напиши правильно на С
Не, я на C не пишу, только на C++. Это надо у местных C'шников спрашивать
0
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
19.01.2015, 09:54 71
Izual, с таким предвосхищением ошибок перед каждой программной инструкцией надо ставить проверку, что программа еще работает, состояние памяти, отведенной для проги не изменилось, контрольные суммы будущей операции валидны. А после операции проверять все то же самое + погоду на Марсе
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 11:10  [ТС] 72
Цитата Сообщение от saden Посмотреть сообщение
с таким предвосхищением ошибок перед каждой программной инструкцией надо ставить проверку
Не страшно, я платформу пишу, автоматический GetLastError будет после каждой вызванной апи функции. Если измерение погоды на марсе было бы апи функцией, то и она бы проверялась, если бы использовалась.
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
19.01.2015, 12:10 73
Цитата Сообщение от Izual Посмотреть сообщение
Я для чего делал топик? - Чтоб найти выход, вы же мне показываете то что "выхода нет" своим выводом.
В начале топика приводился new не вызывающий конструкторов. Вот это собственно и выход:
1) Не использовать конструкторы и функции плюющиеся исключениями.
2) Тщательно проверять что конструктор и используемые функции не будут плеваться исключениями. То есть, отказаться от минимум std::string, std::map, etc (могут выкинуть исключение "памяти мало").
0
184 / 168 / 53
Регистрация: 27.01.2013
Сообщений: 788
19.01.2015, 12:32 74
Цитата Сообщение от Izual Посмотреть сообщение
Не страшно, я платформу пишу
Тогда от new лучше отказаться и вернуться к malloc или вообще к инструкциям ассемблера.
0
143 / 122 / 21
Регистрация: 13.11.2012
Сообщений: 1,564
19.01.2015, 12:37  [ТС] 75
Цитата Сообщение от Renji Посмотреть сообщение
конструкторы и функции плюющиеся исключениями
Так если я использую new[], и выделяю память большего размера нежели есть в наличии, то будет как раз это исключение... ну это я говорю основываясь на том что было описано выше в постах.
Цитата Сообщение от Renji Посмотреть сообщение
проверять что конструктор и используемые функции не будут плеваться исключениями
Как\где их все узнать?..

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

Для этого:
1. Я оставил ссылку на онлайн компилятор с демонстрацией кода в работе
2. Оставил рекомендацию взять в руки любой букварь для самых маленьких, раздел "работа с исключениями".
0
19.01.2015, 13:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.01.2015, 13:34
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
78
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru