1
votes

C ++ try catch ne fonctionne pas pour un tableau hors des limites

Nous avons une application C ++ basée sur QT. Dans lequel nous utilisons également des DLL tierces. Mais, C ++ try and catch ne fonctionne pas du tout.

Par exemple:

#include <QCoreApplication>
#include <QDebug>
#include <QException>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int arr[10];
    try
    {
        arr[11] = 30;
    }
    catch (const std::out_of_range& e)
    {
        qDebug() << "Exception out of range occurred ..." << e.what();
    }
    catch (...)
    {
        qDebug() << "Unknown Exception occured...";
    }

    return a.exec();
}

Voici l'exemple minimal. En haut, il plante le programme. Y a-t-il un moyen de gérer cela?


7 commentaires

Essayez qDebug () << "Exception <" + e.what () + "> s'est produite ..."; dans votre première capture - l'avez-vous déjà vu? Vos deux messages d'erreur étant identiques peuvent prêter à confusion


exemple minimal reproductible s'il vous plaît. où déclarez-vous m_Qmutex par exemple.


Modification de l'échantillon pour avoir MCVE, merci Joey et Neil.


Cet exemple ne fonctionne pas tout à fait non plus, car sortir des limites avec operator [] et un int * n'est pas censé lever une exception!


L'écriture hors des limites du tableau est un comportement indéfini. Il n'est pas nécessaire de planter, de lever une exception ou de faire quoi que ce soit. Pardon.


Nous avons une application héritée, et nous avons des plantages comme mentionné ci-dessus, également une exception de pointeur nul, existe-t-il un moyen d'empêcher le blocage de l'application.


Dans ce cas, écrire un std :: set_terminate, vous aidera?


3 Réponses :


0
votes

Pour répondre à votre question:

"C ++ try catch ne fonctionne pas pour une bibliothèque tierce"

Non! C ++ try catch fonctionne avec la bibliothèque tierce ( Qt ), comme indiqué dans l'exemple ci-dessous.

Mais le code que vous affichez ne l'est pas un mcve . Il est donc difficile de dire quelle est exactement la cause du problème que vous dites avoir.

#include <QCoreApplication>
#include <QDebug>
#include <QException>

class testException : public QException
{
public:
    testException(QString const& message) :
        message(message)
    {}

    virtual ~testException()
    {}

    void raise() const { throw *this; }
    testException *clone() const { return new testException(*this); }

    QString getMessage() const {
        return message;
    }
private:
    QString message;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    try
    {
        // throw std::out_of_range("blah");
        throw testException("blah");
    }
    catch (const std::out_of_range& e)
    {
        qDebug() << "Exception out of range occurred ...";
    }
    catch (...)
    {
        qDebug() << "Unknown Exception occured...";
    }

    return a.exec();
}


0 commentaires

0
votes

std :: out_of_range

Il peut être lancé par les fonctions membres de std :: bitset et std :: basic_string , par std :: stoi et < code> std :: stod familles de fonctions, et par les fonctions d'accès aux membres vérifiées par les limites (par exemple std :: vector :: at et std :: map :: at )

Votre bloc try ne contient aucune de ces choses. L'accès hors limites aux tableaux simples de style C est un comportement non défini . Cela se manifeste souvent par des plantages, comme vous l'avez vécu.


0 commentaires

1
votes

La lecture ou l'écriture hors des limites du tableau est un comportement indéfini. Il n'y a aucune garantie qu'il plantera, lancera une exception ou fera quoi que ce soit. C'est juste du code mal formé.

Si vous voulez un conteneur de type tableau avec vérification des limites, std :: array , std :: vector < / code> , et peut-être std :: deque dans la bibliothèque standard. Ils ont tous une fonction membre at () qui vérifie les limites et lèvera une exception std :: out_of_range .


4 commentaires

Dans ce cas, écrire un std :: set_terminate, vous aidera?


@hetalagrawal La définition d'un gestionnaire de terminaison est utile pour gérer le cas où la gestion des exceptions échoue (comme un std :: out_of_range non intercepté). Rappelez-vous que le hors-limites sur un tableau simple est un comportement indéfini, donc std :: set_terminate n'est pas la solution pour le code de votre question.


Pourquoi nous ne pouvons pas gérer l'accès au pointeur nul en utilisant le bloc try, catch en c ++ La raison est-elle la même car elle conduit à un comportement indéfini?


@hetalagrawal Un segfault causé par un accès de pointeur nul n'est pas une exception C ++. Voir: Est-il possible d'attraper un segfault avec try / attraper?