Аватар для orange_fox
34 / 34 / 8
Регистрация: 06.04.2014
Сообщений: 189

Ошибка при работе с std::exception*

16.02.2015, 23:44. Показов 4410. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему в случаях 1 и 3 выводится нормальный e.what(), а во втором - ошибочный? Как это исправить?
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
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
 
using namespace std;
 
struct testException : public exception
{
    testException() : exception("Test"){}
};
 
struct intException: public exception
{
    intException(int N){
        ostringstream os;
        os << "int: " << N;
        str = os.str();
    }
    virtual const char* what() const throw(){
        return str.c_str();
    }
    string str;
};
 
int main()
{
    //===========================1==========================//
    try{
        testException e;
        exception* ePtr = &e;
        throw *ePtr;
    }
    catch (exception& e)
    {
        //e.what() == "Test"
        cout << "std::exception:\t" << e.what() << endl;
    }
    catch (...){
        cout << "Catched unknown exception" << endl;
    }
    //===========================2===========================//
 
    try{
        intException e(13);
        exception* ePtr = &e;
        throw *ePtr;
    }
    catch (exception& e)
    {
        //e.what() == "Unknown exception"
        cout << "std::exception:\t" << e.what() << endl;
    }
    catch (...){
        cout << "Catched unknown exception" << endl;
    }
    //===========================3===========================//
 
    try{
        throw intException(13);
    }
    catch (exception& e)
    {
        //e.what() == "int: 13"
        cout << "std::exception:\t" << e.what() << endl;
    }
    catch (...){
        cout << "Catched unknown exception" << endl;
    }
    //=======================================================//
    system("pause");
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.02.2015, 23:44
Ответы с готовыми решениями:

Ошибка terminate called after throwing an instance of 'std::bad_alloc' при работе с типом std::string
Добрый вечер, при работе функции возникает ошибка terminate called after throwing an instance of 'std::bad_alloc' what(): ...

Ошибка при написании класса: Unhandled exception std::bad_alloc at memory location
ПИшу свой клас Var, проблема в следующем из-за строчки first = first+1; вылетает ошибка Unhandled exception at at 0x760FB727 in...

Unhandled exception at at 0x75E717D2 in ConsoleApplication24.exe: Microsoft C++ exception: std::out_of_range at memory l
Здравствуйте, помогите пожалуйста, при проходе через последний цикл выдаёт вот такую ошибку: Unhandled exception at at 0x75E717D2 in...

8
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,769
16.02.2015, 23:51
Цитата Сообщение от orange_fox Посмотреть сообщение
Почему в случаях 1 и 3 выводится нормальный e.what(), а во втором - ошибочный?
Потому что "срезка".
В С++ копирование объектов по значению не полиморфно.
Цитата Сообщение от orange_fox Посмотреть сообщение
Как это исправить?
Не делать так.
1
 Аватар для orange_fox
34 / 34 / 8
Регистрация: 06.04.2014
Сообщений: 189
16.02.2015, 23:56  [ТС]
DrOffset, Так я ж вроде не копировал(по значению)...
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.02.2015, 00:00
Во-первых, код не валидный с точки зрения Стандарта (т.е. не компилируется в gcc например). В частности из-за отсутствия конструктора std::exception, принимающего строку.
Во-вторых, как уже упомянул DrOffset, при разыменовании указателя получаешь срезку.
Чтобы исправить, вызови в intException соответствующий конструктор для std::exception:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct intException : public exception
{
    intException(int N)
        : exception( name(N).c_str() ) { }
 
private:
    static std::string name(int N) 
    { 
        ostringstream os;
        os << "int: " << N;
        return os.str();
    }
};
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,769
17.02.2015, 00:13
Цитата Сообщение от orange_fox Посмотреть сообщение
Так я ж вроде не копировал(по значению)
Копирует throw.
C++
1
2
3
4
5
6
7
8
9
10
try{
    intException e(13);
    exception* ePtr = &e;
    throw *ePtr; // <-   *ePtr тут копируется, исходный тип exception, следовательно копируется только содержимое exception, получаем срезку.
}
catch (exception& e)
{
    //e.what() == "Unknown exception"
    cout << "std::exception:\t" << e.what() << endl;
}
1
 Аватар для orange_fox
34 / 34 / 8
Регистрация: 06.04.2014
Сообщений: 189
17.02.2015, 00:15  [ТС]
Цитата Сообщение от Tulosba Посмотреть сообщение
Во-вторых, как уже упомянул DrOffset, при разыменовании указателя получаешь срезку.
Если при разыменовании происходит срезка, то почему этот код выводит ошибку нормально?
C++
1
2
3
4
    intException e(13);
    exception* ePtr = &e;
    cout << ePtr->what() << endl; //"int: 13"
    cout << (*ePtr).what() << endl;//"int: 13"
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,769
17.02.2015, 00:17
Цитата Сообщение от orange_fox Посмотреть сообщение
Если при разыменовании происходит срезка, то почему этот код выводит ошибку нормально?
Срезка происходит при копировании, а не при разыменовании. Операция throw копирует исключение.
1
 Аватар для orange_fox
34 / 34 / 8
Регистрация: 06.04.2014
Сообщений: 189
17.02.2015, 00:20  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Не делать так.
А так можно делать? Вроде работает и срезки не должно быть.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    intException e(13);
    exception* ePtr = &e;
 
    try{
        throw ePtr;
    }
    catch (exception* e)
    {
        //e.what() == "int: 13"
        cout << "std::exception*:\t" << e->what() << endl;
    }
    catch (exception& e)
    {
        cout << "std::exception:\t" << e.what() << endl;
    }
    catch (...){
        cout << "Catched unknown exception" << endl;
    }
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,769
17.02.2015, 00:28
Лучший ответ Сообщение было отмечено orange_fox как решение

Решение

Цитата Сообщение от orange_fox Посмотреть сообщение
почему этот код выводит ошибку нормально?
Потому что полиморфизм в С++ работает со ссылками. А разыменование в данном случае дает тип
C++
1
exception &
следовательно получаем полиморфный вызов what().

Добавлено через 2 минуты
Цитата Сообщение от orange_fox Посмотреть сообщение
А так можно делать?
Можно, не бессмысленно. В реальной ситуации в контексте выполнения, где было брошено исключение не остается живых объектов (раскрутка стека ведь). Поэтому для того, чтобы это гарантированно работало, нужно вносить в код специальные изменения. Следить за временем жизни intException e. Такой код неинтуитивный и потенциально ошибкоопасный. Но делать можно, да.

Добавлено через 4 минуты
orange_fox, Вот. И вообще книгу эту (Стандарты программирования на C++) советую прочитать. И другие на эту тему (Саттер, Мейерс).
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.02.2015, 00:28
Помогаю со студенческими работами здесь

Unhandled exception при работе с матрицами
Делал лабораторную работу....и вот уже битых часа 3 сиже немогу понять в чем проблема и как ее испрвить вот условие задачи ...

Выдаёт ошибку "Unhandled exception at 0x00007F exception: std::bad_alloc in memory location"
Добрый день, друзья не могли бы помочь разобраться, почему выдаёт такую ошибку? Вот #include &lt;iostream&gt; #include...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

Вылетает на std::length_error exception
название не очень отражает суть вопроса, но лучше я предумать не смог. Есть программа собранная в дебаге (-g) к ней линкуется только одна...

Грамотно обработать ошибку std::exception
struct Node { Node(int data): data_(data) {} int data_; // полезная часть списка Node* next; // указатель на следующий...


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

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

Новые блоги и статьи
Blazor и контроллер сервопривода IoT Meadow Maple
Wired 11.07.2025
Я решил разобраться, как можно соединить современные веб-технологии с миром "железа". Интересная комбинация получилась из Blazor в качестве веб-интерфейса и микроконтроллера Meadow с его веб-сервером. . .
Генерация OpenQASM из кода Q#
EggHead 10.07.2025
Летом 2024-го я начал эксперименты с библиотекой Q# Bridge, и знаете что? Она оказалась просто находкой для тех, кто работает на стыке разных квантовых экосистем. Основная фишка этой библиотеки -. . .
Изучаем новый шаблон ИИ-чата .NET AI Chat Web App
stackOverflow 10.07.2025
В . NET появилось интересное обновление - новый шаблон ИИ-чата под названием . NET AI Chat Web App. Когда я впервые наткнулся на анонс этого шаблона, то сразу понял, что Microsoft наконец-то. . .
Результаты исследования от команды ARP (июль 2025 г.)
Programma_Boinc 10.07.2025
Результаты исследования от команды ARP (июль 2025 г. ) Африканский проект по дождям (ARP) World Community Grid снова запущен! Мы рады поделиться обновленной информацией о нашем прогрессе с осени. . .
Angular vs Svelte - что лучше?
Reangularity 09.07.2025
Сегодня рынок разделился на несколько четких категорий: тяжеловесы корпоративного уровня (Angular), гибкие универсалы (React), прогрессивные решения (Vue) и новая волна компилируемых фреймворков. . .
Code First и Database First в Entity Framework
UnmanagedCoder 09.07.2025
Entity Framework дает нам свободу выбора, предлагая как Code First, так и Database First подходы. Но эта свобода порождает вечный вопрос — какой подход выбрать? Entity Framework — это. . .
Как использовать Bluetooth-модуль HC-05 с Arduino
Wired 08.07.2025
Bluetooth - это технология, созданная чтобы заменить кабельные соединения. Обычно ее используют для связи небольших устройств: мобильных телефонов, ноутбуков, наушников и т. д. Работает она на частоте. . .
Руководство по структурам данных Python
AI_Generated 08.07.2025
Я отчетливо помню свои первые серьезные проекты на Python - я писал код, он работал, заказчики были относительно довольны. Но однажды мой наставник, взглянув на мою реализацию поиска по огромному. . .
Тестирование энергоэффективности и скорости вычислений видеокарт в BOINC проектах
Programma_Boinc 08.07.2025
Тестирование энергоэффективности и скорости вычислений видеокарт в BOINC проектах Опубликовано: 07. 07. 2025 Рубрика: Uncategorized Автор: AlexA Статья размещается на сайте с разрешения. . .
Раскрываем внутренние механики Android с помощью контекста и манифеста
mobDevWorks 07.07.2025
Каждый Android-разработчик сталкивается с Context и манифестом буквально в первый день работы. Но много ли мы задумываемся о том, что скрывается за этими обыденными элементами? Я, честно говоря,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru