C++
3 / 3 / 1
Регистрация: 21.10.2017
Сообщений: 121
1

Выдаёт ошибку при динамическом выделении памяти

01.10.2018, 13:50. Показов 943. Ответов 14

В строчке
C++
1
cout << "Значение по адресу " << p << " равно: " << *p << endl;
Компилятор ругается:
используется потенциально неинициализированная локальная переменная-указатель "p"
Почему так? Как решить эту проблему?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <conio.h>
#include <new>
using namespace std;
int main() {
    setlocale(LC_ALL, "");
    int *p;
    try {
        p = new int (87);
    }
    catch (bad_alloc except) {
        cout << "Невозможно выделить память.\n";
    }
    cout << "Значение по адресу " << p << " равно: " << *p << endl;
    _getch();
    return 0;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.10.2018, 13:50
Ответы с готовыми решениями:

Ошибка при динамическом выделении памяти
почему у меня возникет ошибка вот тут struct TOVAR *New = new struct TOVAR; пишит недопустимый...

Ошибка при динамическом выделении памяти
Я не понимаю почему, но почему-то пример по динамическому выделению памяти, взятый с этой...

Создание исключения при динамическом выделении памяти
Вот код из учебника в нем мне все понятно. #include&lt;iostream&gt; #include&lt;cstdlib&gt; //exit()...

Выравнивание при динамическом выделении памяти под массив
Добрый вечер. Для того, чтобы выделить память под массив динамически и выровнять указатель по 16...

14
1372 / 760 / 201
Регистрация: 10.02.2018
Сообщений: 3,144
01.10.2018, 14:01 2
У меня вот, что выдало C::B 17.12
Выдаёт ошибку при динамическом выделении памяти
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.10.2018, 14:01 3
Цитата Сообщение от JustLearn Посмотреть сообщение
Почему так? Как решить эту проблему?
1) Потому, что если память не сможет выделиться - p останется неинициализированным.
2) int *p = nullptr; (или в catch его занулите - но это хуже).
0
1372 / 760 / 201
Регистрация: 10.02.2018
Сообщений: 3,144
01.10.2018, 14:02 4
P.S. а если так:
C++
1
 int *p = NULL;
0
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 856
01.10.2018, 14:08 5
А если
C#
1
int* p = nullptr;
0
Эксперт С++
8711 / 4293 / 956
Регистрация: 15.11.2014
Сообщений: 9,733
01.10.2018, 14:39 6
Цитата Сообщение от JustLearn Посмотреть сообщение
Почему так?
потому что:
Цитата Сообщение от JustLearn Посмотреть сообщение
используется потенциально неинициализированная локальная переменная-указатель "p"
тут вроде по-русски написано, не?

Цитата Сообщение от JustLearn Посмотреть сообщение
Как решить эту проблему?
написать код по человечачьи:

C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
int main() {
    try {
        int* p = new int (87);
        cout << "Значение по адресу " << p << " равно: " << *p << endl;
    }
    catch (const std::bad_alloc& e) {
        cout << "Невозможно выделить память:" << e.what() << endl;
    }
}
0
C++
3 / 3 / 1
Регистрация: 21.10.2017
Сообщений: 121
05.10.2018, 23:46  [ТС] 7
Серж762, Jman, работает! А почему?)) Я не знаю, что такое nullptr и что такое NULL и за что они отвечают. Объясните пожалуйста

Добавлено через 3 минуты
Цитата Сообщение от avgoor Посмотреть сообщение
1) Потому, что если память не сможет выделиться - p останется неинициализированным.
2) int *p = nullptr; (или в catch его занулите - но это хуже).
Ну 1-ый вариант у меня обработан в исключении. Причиной недуга стал 2-ой. Поставив int*p = nullptr; всё заработало. Вопрос: почему?) В каких случаях надо ставить nullptr?

Добавлено через 32 секунды
avgoor, объясните пожалуйста
0
"C with Classes"
1590 / 1369 / 512
Регистрация: 16.08.2014
Сообщений: 5,696
Записей в блоге: 1
06.10.2018, 07:41 8
Цитата Сообщение от JustLearn Посмотреть сообщение
В каких случаях надо ставить nullptr?
на первое время можешь считать что nullptr это 0 или NULL. Как я понимаю, предупреждение компилятора об используемой не инициализированной локальной переменной это особенность компилятора а не стандарт, по стандарту использование не инициализированной локальной переменной это UB.
Короче компилятор тебе говорит "Лучше поставь nullptr, а то будет хреново потом." Хреново это значит что ты можешь попробовать обратиться к памяти по этому указателю а там черт знает что, короче UB.
В С++ у указателей может быть строго два состояния рабочий, то есть в нем храниться какой то адрес, или не рабочий, то есть содержит 0, если ты напишешь просто int* p; в нем будет содержаться мусор, мусор - не корректный адрес, а это плохо.

P.S. Вот если созрел...

Не следует использовать значение NULL или ноль (0) в качестве константы-указателя null; ключевое слово nullptr менее уязвимо для неправильного использования и лучше работает в большинстве случаев. Например, если для функции func(std::Pair<const char *, double>) произвести вызов func(std::make_pair(NULL, 3.14)), возникнет ошибка компилятора. Макрос NULL разворачивается в 0, поэтому вызов std::make_pair(0, 3.14) возвращает значение std::Pair<int, double>, которое невозможно преобразовать к типу параметра std::Pair<const char *, double> функции func(). Вызов func(std::make_pair(nullptr, 3.14)) успешно компилируется, поскольку std::make_pair(nullptr, 3.14) возвращает значение std::Pair<std::nullptr_t, double>, которое допускает преобразование в тип std::Pair<const char *, double>.
1
C++
3 / 3 / 1
Регистрация: 21.10.2017
Сообщений: 121
07.10.2018, 15:16  [ТС] 9
_stanislav, вроде бы я всё понял. Т.е. получается, что какие-то компиляторы требует написания nullptr , а какие-то нет. Если не написать nullptr в том компиляторе, который это требует, то сработает ошибка. Некоторые компиляторы просят писать nullptr чтобы не происходило неопределенного поведения (UB). Я верно всё усвоил?

Добавлено через 6 минут
И ещё лучше всего во всех случаях использовать nullptr, т.к. оно менее уязвимо для неправильного использования.

Добавлено через 5 минут
Но есть одна вещь, которую я не очень хорошо понял из того, что Вы написали.
Цитата Сообщение от _stanislav Посмотреть сообщение
Не следует использовать значение NULL или ноль (0) в качестве константы-указателя null
Можете привести простенький пример в коде с константой-указателем null? Я не прошу какую-то программу. Хотя бы просто как это написать в коде

Я думаю это что-то вроде:
const null *ptr;
0
Don't worry, be happy
17769 / 10534 / 2034
Регистрация: 27.09.2012
Сообщений: 26,505
Записей в блоге: 1
07.10.2018, 16:11 10
Цитата Сообщение от _stanislav Посмотреть сообщение
предупреждение компилятора об используемой не инициализированной локальной переменной это особенность компилятора а не стандарт
Стандарт не требует диагностики, но и не запрещает.
Цитата Сообщение от _stanislav Посмотреть сообщение
В С++ у указателей может быть строго два состояния рабочий, то есть в нем храниться какой то адрес, или не рабочий, то есть содержит 0
Эм... чего?
Цитата Сообщение от _stanislav Посмотреть сообщение
если ты напишешь просто int* p; в нем будет содержаться мусор, мусор - не корректный адрес, а это плохо.
Зависит от типа инициализации, которая будет применена для указателя,
т.е. от того, где это объявление происходит. В коде ТС там мусор, да.

Цитата Сообщение от JustLearn Посмотреть сообщение
Я верно всё усвоил?
Нет.

Цитата Сообщение от JustLearn Посмотреть сообщение
Т.е. получается, что какие-то компиляторы требует написания nullptr , а какие-то нет.
Никакие не требуют.
Цитата Сообщение от JustLearn Посмотреть сообщение
Если не написать nullptr в том компиляторе, который это требует, то сработает ошибка.
Нет. Вам же пишут в чем заключается ошибка:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    int *p;//В данном случае куда указывает указатель? Куда-то, неизвестно куда.
    try {
        p = new int (87);//Если здесь вылетело исключение, то p не изменится и 
    }
    catch (bad_alloc except) {//и управление уходит в catch
        cout << "Невозможно выделить память.\n";
    }//после чего выполнение продолжается уже за try
    //а здесь используется p, который содержит непонятно что.
    //так что должно получиться при *p, если p хрен знает куда смотрит?
    cout << "Значение по адресу " << p << " равно: " << *p << endl;
    //вот компилятор и орет, что нашел такую вот багу в твоем коде -
    //использование потенциально неинициализированной переменной
А если изначально инициализировать p, то компилятор перестанет ругаться этими гадкими словами, но при это проблема никуда не уйдет:
C++
1
2
3
4
5
6
7
8
9
10
    int *p = nullptr;//Теперь у нас указатель инициализирован
    try {
        p = new int (87);//Если здесь вылетело исключение, то p не изменится и 
    }
    catch (bad_alloc except) {//и управление уходит в catch
        cout << "Невозможно выделить память.\n";
    }//после чего выполнение продолжается уже за try
    //а здесь используется p, который содержит nullptr.
    //так что должно получиться при *p?
    cout << "Значение по адресу " << p << " равно: " << *p << endl;
То есть, вне зависимости от инициализации указателя значением nullptr,
структура данного кода не позволяет нормально работать.
Цитата Сообщение от JustLearn Посмотреть сообщение
Некоторые компиляторы просят писать nullptr чтобы не происходило неопределенного поведения (UB)
Нет, Ваш компилятор просит писать код так, чтобы не было использования неинициализированной переменной.
hoggy привел пример как написать код, чтобы такого использования не было.
0
"C with Classes"
1590 / 1369 / 512
Регистрация: 16.08.2014
Сообщений: 5,696
Записей в блоге: 1
07.10.2018, 21:16 11
Croessmah, да да да тащи стандарт сю
Цитата Сообщение от Croessmah Посмотреть сообщение
Эм... чего
что случилось? или тебе опять поговорить не с кем?
0
Don't worry, be happy
17769 / 10534 / 2034
Регистрация: 27.09.2012
Сообщений: 26,505
Записей в блоге: 1
07.10.2018, 21:19 12
Цитата Сообщение от _stanislav Посмотреть сообщение
что случилось?
Фигня написана, вот дар речи и потерял.
Какие еще рабочее и не рабочее состояния?
Что это за пьяная выходка?
0
"C with Classes"
1590 / 1369 / 512
Регистрация: 16.08.2014
Сообщений: 5,696
Записей в блоге: 1
07.10.2018, 21:22 13
Croessmah, тебе какая разница вообще, я хочу что бы человек меня понял.
0
Don't worry, be happy
17769 / 10534 / 2034
Регистрация: 27.09.2012
Сообщений: 26,505
Записей в блоге: 1
07.10.2018, 21:27 14
_stanislav, поэтому буду придумывать отсебятину, которая никак не связана с действительностью? Логично.
0
_stanislav
07.10.2018, 23:21     Выдаёт ошибку при динамическом выделении памяти
  #15

Не по теме:

ладно

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.10.2018, 23:21

Cin.getline() не работает при динамическом выделении памяти
Почему в таком коде cin.getline() работает не так как надо? Если очистить поток, то будет все...

Использование конструктора базового класса при динамическом выделении памяти
Есть базовый класс, от него наследуются несколько классов, свой конструктор я определил в базовом...

Ошибка на динамическом выделении памяти
программа ниже безупречно выполнялась под С++Builder 6.0 (консольное приложение). При переводе ее...

Немного о динамическом выделении памяти ...
объявление данных в классе: class Employee {.......... private: char *firstName;...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru