Sunteți pe pagina 1din 7

Tratarea excepiilor n C

Afiarea de erori i continuarea execuiei


programului
n Afiarea de erori i terminarea programului

Tratarea Excepiilor

scanf(%d,&n);
if (n>MAX) {
printf(Depasire valare maxima);
exit(1);
}

Mihai Gabroveanu

Tratarea Excepiilor

Ce este o excepie?

Tratarea excepiilor n C

O excepie este o eroare care poate s apar


la rularea unui program.
n Exemple:

ncercarea

de deschidere a unui fiier ce nu exist


depirea limitelor unui tablou
ncercarea de alocare a unui spaiu de memorie
ce depete dimensiunea heap-ului
etc.
Tratarea Excepiilor

Testarea valorilor returnate de anumite funcii, cu privire la


posibilele erori ce au aparut pe parcursul execuiei acestora
Exemplu
if (scanf(%d %d,&n,&m)!=2) {
printf(valori invalide);
exit(1);
}
float *p= (float *) malloc(sizeof(float));
if (p==NULL){
printf(eroare alocare memorie);
exit(1);
}

Tratarea Excepiilor

Tratarea excepiilor n C
n

Exemplu: Clasa Vector


class Vector {
private:
float t[MAX];
int n;
public:
Vector(int n);
int getNrElemente() const;
void setElement(int i, float val);
float getElement(int i) const;
void citire();
void afisare();
};
Vector::Vector(int n){
assert(n<=MAX);
this->n = n;
for (int i = 0; i < n; i++){
this->t[i] = 0;
}
}

Utiliznd macrodefiniia assert. Sintax


assert(expresie);
Dac valoarea expresiei este fals atunci se oprete
execuia programului i se afieaz un mesaj de eroare
care indic fiierul i linia unde este poziionat
macrodefiniia.
Dac valoarea expresiei este adevarat atunci execuia
programului se continu.
Avantaj: poate fi inactivat n momentul preprocesrii
astfel:
#define NDEBUG

Tratarea Excepiilor

Exemplu: assert
#include <assert.h>
#include <iostream>
#define MAX 100
using namespace std;
int main(){
int t[MAX];
int i,n;
cout<<Introduceti n:;
cin>>n;
assert(n<MAX);
for(i=0;i<n;i++){
cin>>t[i];
}
}

void Vector::setElement(int i,float val){


if (i >= 0 && i < n){
t[i] = val;
} else {
cerr<<"Index invalid: "<<i<<endl;
}
}
float Vector::getElement(int i) const {
if (i>=n){
cerr<<"Index invalid: "<<i<<endl;
exit(1);
}
return t[i];
}

Tratarea Excepiilor

Exemplu: Clasa Vector (cont.)


Introduceti n:203
Assertion failed: n<MAX, file
TestAssert.cpp, line 11
This application has requested the
Runtime to terminate it in an unusual
way.
Please contact the application's support
team for more information.

Tratarea Excepiilor

int Vector::getNrElemente() const {


return n;
}
void Vector::citire(){
int i;
cout<<"Dati elementle vectorului:";
for (i = 0; i < n; i++){
cin >> t[i];
}
}
void Vector::afisare() {
int i;
for (i = 0; i < n; i++){
cout<<t[i]<<" ";
}
cout<<endl;
}

void tratareTerminare (){


cout<<"Terminare program!"<<endl;
}
Se apeleaz automat la terminarea
programului.
int main(){
Se pot trata eventualele erori
int n;
atexit(tratareTerminare);
Vector v(2);
v.setElement(0,4);
v.setElement(3,9);

v.afisare();
getch();
return 0;
}

Tratarea Excepiilor

Dezavantajele tratrilor erorilor n C

Generarea i prinderea excepiilor

Secvena de apel al unei funcii ce returneaz


un cod e eroare trebuie sa fie nsoit de
foarte multe if-uri pentru a trata posibilele erori
n Dezavantajul major: codul de tratare a erorilor
devine dependent, cuplat de logica aplicaiei

Tratarea Excepiilor

C++ are un mecanism avansat de tratare a erorilor,


codul ce trateaz erorile fiind decuplat de logica
aplicaiei:

11

Aruncarea (generarea) unei excepii se face


cu ajutorul intruciunii throw
n Sintaxa:
throw [<expresie>];
n Exemplu:

Iniial scriem codul care dorim s se execute, apoi separat,


Se scrie codul ce trateaz situaiile neprevazute

O excepie n C++ este un obiect al unei clase ce


este generat la apariia unei erori i cuprinde de
regul informaii sumare despre cauza erorii.

Tratarea Excepiilor

Tratarea Excepiilor

Generarea Excepiilor: throw

Suspendarea execuiei funciei curente n momentul n


care s-a detectat o eroare, generarea unei excepii care
conine informaii referitoare la eroare i aruncarea
(throw) ei ctre funcia apelant;
Reluarea execuiei programului n alt zon, prinderea
(catch) excepiei i executarea aciunilor necesare tratrii
erorilor.

Tratarea excepiilor n C++


n

Mecanismul de tratare a excepiilor presupune:

throw out_of_range("Depasire limite");


throw 1;
10

Tratarea Excepiilor

12

Generarea Excepiilor: throw (cont.)


n

Prinderea excepiilor: try/catch(cont.)


n

Mod de execuie:

se suspend execuia funciei curente;


se creaz un obiect corespunztor valorii expresiei ce
urmeaz cuvntului throw;
obiectul creat este returnat ctre contextul apelant, chiar
dac el nu corespunde tipului valorii de return a funciei.
nainte de parasire a funciei toate obiectele create local
sunt distruse (se apeleaz destructori acestora)

Prinderea excepiilor: try/catch


n

Tratarea Excepiilor

Tratarea Excepiilor

15

Exemplu
class E {
public:
const char* mesaj;
E(const char* m) : mesaj(m) { }
};
void f(int n){
switch (n){
case 1:
throw 0.5;
cout<<"Intructiune ce nu se va executa";
case 2:
case 3:
throw E("Eroare n este 2 sau 3");
cout<<"Intructiune ce nu se va executa";
case 4:
throw n;
}
cout<<"Terminare funtie f()"<<endl;
}

Repionarea (prinderea) unei excepii se face utiliznd blocul


de instruciuni try/catch
Sintaxa:

try {
// secven de intruciuni ce poate genera excepii
} catch (TipExceptie1 ex1){
//tratare excepie de tip TipExceptie1
} catch (TipExceptie2 ex2){
//tratare excepie de tip TipExceptie2
...
} catch (TipExceptieN exN){
//tratare excepie de tip TipExceptieN
} catch () {
//tratare orice alta excepie ce poate aparea
}

try marcheaz nceputul unui bloc de instruciuni care pot genera


(arunca) excepii
dac la execuia unei intruciuni este aruncat o excepie atunci se
abandoneaz execuia instruciunilor din bloc i se ncearc
(prinderea) identificarea tipului obiectului aruncat cu unul dintre tipurile
specificat n ramurile catch: TipExceptie1, TipExceptie2, etc.
Dac se identific o ramur catch pentru care tipul excepiei coincide
se va executa secvena de instruciuni pentru tratarea acelui tip de
excepie
n cazul n care tipul excepiei aruncate nu coincide cu nici unul din
tipurile specificate in ramurile catch si exist ramura catch() atunci se
vor executa instruciunile din acel bloc

13

Tratarea Excepiilor

Mod de execuie:

Handlere de tratare
a erorilor

14

int main (){


int n;
cin>>n;
try{
cout<<"Execut functia f("<<n<<")\n";
f(n);
cout<<"Executie cu succes"<<endl;
} catch (double n){
cerr<<"Tratare eroare de tip double: "<<n;
} catch (E e){
cerr<<"Tratare eroare de tip E: "<<e.mesaj;
} catch (...){
cerr<<"Tratare eroare necunoscuta";
}
getch();
}

Tratarea Excepiilor

16

Exemplu (cont.)

Specificarea excepiilor generate

OUTPUT:

n=1
Execut functia f(1)
Tratare eroare de tip double: 0.5 n=1
n=3
Execut functia f(3)
Tratare eroare de tip E: Eroare n este 2 sau 3

tipr numeFunctie(lista_parametri) throw (TipE1,TipE2, , TipEn){


}

n=4
Execut functia f(4)
Tratare eroare necunoscuta

n=5
Execut functia f(5)
Terminare funtie f()
Executie cu succes

17

Potrivirea Excepiilor

n
n
n

Dac dorim s specificm c o funcie nu genereaz


nicio excepie atunci folosim urmtoarea sintax:
tipr numeFunctie(lista_parametri) throw (){
}

Tratarea Excepiilor

Pentru a specifica faptul c o funcie genereaz


numai un anumit set de excepii de anumite tipuri
atunci utilizm urmtoarea sintax:

19

Exemplu

La aruncarea unei exceptii, se cauta cel mai


apropiat handler n raport cu ordinea n care
acetia apar n cod
La gasirea unei potriviri, cautarea se opreste
Polimorfismul functioneaza
E indicat sa prindem o exceptie prin referinta, pentru
a evita apelul constructorului de copiere sau folosind
pointeri
Tratarea Excepiilor

Tratarea Excepiilor

18

void f(int n) throw (double, E, int){


switch (n){
case 1:
throw 0.5;
cout<<"Intructiune ce nu se va executa";
case 2:
case 3:
throw E("Eroare n este 2 sau 3");
cout<<"Intructiune ce nu se va executa";
case 4:
throw n;
}
}

Tratarea Excepiilor

20

Excepii netratate

Tipuri de excepii predefinite

Dac un bloc try/catch nu trateaz (prinde) un


anumit tip de excepie atunci excepia
respectiv este aruncat ctre contextul
superior.
n Daca o ecepie nu e tratata de nici un handler,
se va apela functia terminate(), care apeleaz
la randul sau abort() iesirea din program
n

Tratarea Excepiilor

21

Rearuncarea unei excepii


n
n

Tratarea Excepiilor

Tipuri de excepii predefinite (cont)

Dac se dorete rearuncarea unei exceptii prinse ctre contextul superior


atunci se foloseste clauza throw fr nici un argument.
De obicei, atunci cnd nu suntem interesati de cauza exceptiei, ci doar
dorim eliberarea resurseler, folosim clauza catch() pentru a prinde
excepia, eliberm resursele si apoi o aruncam mai departe

Din clasa exception sunt derivate dou clase, logic_error, pentru


raportarea erorilor detectabile nainte de execuia programului i
runtime_error, pentru raportarea erorilor din timpul execuiei programului.
Principalele clase derivate din logic_error sunt urmtoarele:

try{
//instructiuni ce pot genera excepii
} catch(){
//eliberare resurse
throw;
}

22

domain_error raporteaz violarea unei precondiii


invalid_argument argument invalid pentru o funcie
length_error un obiect cu o lungime mai mare dect NPOS (valoarea
maxim reprezentabil)
out_of_range n afara domeniului
bad_cast operaie dynamic_cast eronat

Principalele clase derivate din runtime_error sunt urmtoarele:

Tratarea Excepiilor

23

range_error violarea unei postcondiii


overflow_error operaie aritmetic eronat (depire)
bad_alloc eroare de alocare

Tratarea Excepiilor

24

Exemplu

Tem

class Vector {
private:
float t[MAX];
int n;
public:
Vector(int n);
int getNrElemente() const;
void setElement(int i, float val);
float getElement(int i) const;
void citire();
void afisare();
};
Vector::Vector(int n){
this->n = n;
if(n>MAX)
throw out_of_range("Depasire
dimensiune maxima");
for (int i = 0; i < n; i++){
this->t[i] = 0;
}

}
void Vector::setElement(int i, float val)
{
if (i >= 0 && i < n){
t[i] = val;
} else {
throw out_of_range("Depasire
limite");
}
}
float Vector::getElement(int i) const {
if (i >= 0 && i < n)
return t[i];
else
throw out_of_range("Depasire limite");
}

Tratarea Excepiilor

25

Exemplu (cont.)
int main(){
int n;
Vector v(2);
v.setElement(0,4);
try{
v.setElement(3,9);
} catch (exception &e){
cerr<<"Eroare:"<<e.what()<<endl;
}
v.afisare();
getch();
return 0;
}
OUTPUT:
Eroare:Depasire limite
4 0

Tratarea Excepiilor

26

Implementati clasa Cantar. Un cantar are o


capacitate maxima admisa. Daca se ncearca
cantarirea unui obiect ce depaseste cu maxim 10%
greutatea maxim admis se va genera excepia
AvertismentDepasireGreutate iar daca se depasete
si acesta limita se va genera eroarea
DepasireGreutate.
Implementati clasa Stiva implementata sub forma
unui tablou alocat dinamic. Gestionati exceptiile ce
pot aparea.

Tratarea Excepiilor

27