Error handling?

D

desktop

I have a class that contains:


class MyArray {
public:
MyArray(int a) : num(a){}

void generate() {
ip = new int[a];
}

int& operator[](int Index) {
return ip[Index];
}
....
....

private:
int* ip;
int num;

};


But I assume its rather error-prone. What kind of techniques exist for
handling memory allocation and indexing errors? Eg. is it necessary to
catch a possible bad_alloc thrown by new or out_of_range etc. I would
like to know what the standard approaches towards error-safe code are in
the above example.
 
R

red floyd

desktop said:
I have a class that contains:


class MyArray {
public:
MyArray(int a) : num(a){}

void generate() {
ip = new int[a];
}

int& operator[](int Index) {
return ip[Index];
}
...
...

private:
int* ip;
int num;

};


But I assume its rather error-prone. What kind of techniques exist for
handling memory allocation and indexing errors? Eg. is it necessary to
catch a possible bad_alloc thrown by new or out_of_range etc. I would
like to know what the standard approaches towards error-safe code are in
the above example.

The main one? Use std::vector instead.
 
E

edd

I have a class that contains:

class MyArray {
public:
MyArray(int a) : num(a){}

void generate() {
ip = new int[a];
}

int& operator[](int Index) {
return ip[Index];
}
...
...

private:
int* ip;
int num;

};

But I assume its rather error-prone. What kind of techniques exist for
handling memory allocation and indexing errors? Eg. is it necessary to
catch a possible bad_alloc thrown by new or out_of_range etc. I would
like to know what the standard approaches towards error-safe code are in
the above example.

Preferably use std::vector<>, either out the box, or as the basis for
your implementation. You'll never have to worry about memory leaks.
Copy construction and assignment will "just work". You can forward
your operator[] calls to the vector's at() member function if you want
bounds checking or it's operator[] if you don't.

If you really insist on using new[], then at the very least:

- move the initialisation of the pointer in to the initialiser list in
the constructor.
- consider using a more appropriate type to represent sizes and
indices (my knee-jerk reaction would be to opt for size_t)
- make sure you delete[] the pointer in the destructor
- define what it means for a MyArray to be copy constructed and copy-
assigned, or disallow them completely using the private-and-undefined-
copy-machinery trick.

If the number of elements in a MyArray can change you have a lot of
extra stuff to consider, too, in terms of crafting an efficient
implementation and exception safety. In particular look at the
strategies vector<> implementations use to expand their capacity when
elements are appended/inserted and how they interplay with exceptions.

Of course this all begs the question, why don't you just use an
std::vector<int> as-is? The people that designed it have taken care of
the tricky implementation details for you.

Kind regards,

Edd
 
B

BobR

desktop said:
I have a class that contains:

class MyArray {
public:
MyArray(int a) : num(a){}
void generate() {
// > ip = new int[a];

ip = new int[ num ];
}

int& operator[](int Index) {
return ip[Index];
}
...
...
private:
int* ip;
int num;
};

But I assume its rather error-prone. What kind of techniques exist for
handling memory allocation and indexing errors?

std::vector<int> MyArray( 1, 42);

try{
int aaa = MyArray.at(2);
}
catch(std::eek:ut_of_range const &oor){
std::cout<<" caught = "<<oor.what()<<std::endl;
}

Eg. is it necessary to
catch a possible bad_alloc thrown by new or out_of_range etc. I would
like to know what the standard approaches towards error-safe code are in
the above example.

"necessary" depends on how much damage will be done if the memory allocation
fails inside your class. <G>

In "Thinking in C++" vol.2, Eckel/Allison have a whole chapter dedicated to
'exception handling', and show how to do it inside a class. It should give
you a good start on that. ( it may not be perfect due to changes in standard
since it was 'final'-ized. ).

Get "Thinking in C++", 2nd ed. Volume 1&2 by Bruce Eckel
(available for free here. You can buy it in hardcopy too.):
http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

See: // : C01:InitExcept.cpp From "Thinking in C++, Vol2"
[ preview snippet, modified for ostream output ]
class Derived : public Base {
std::eek:stream &dout;
public:
class DerivedExcept{
char const *msg;
public:
DerivedExcept( char const *msg) : msg(msg){}
char const* what() const { return msg; }
};
Derived(int j, std::eek:stream &out)
try : Base(j, out), dout(out){ // Ctor body
// 'Base' just throws BaseExcept();
out<<"This won't print"<<std::endl;
}
catch( BaseExcept& ){
out<<"catch(BaseExcept&) ";
throw DerivedExcept("Base subobject threw");;
}
~Derived(){ // Dtor
dout<<"~Derived() Dtor called."<<std::endl;
}
}; // class Derived

{ using std::cout; // main or function
try{
Derived d( 3, cout );
}
catch( Derived::DerivedExcept &ddd ) {
cout<<"catch( DerivedExcept &)\n";
cout<<ddd.what()<<std::endl; // "Base subobject threw"
}
}

Or, check the book you have for something similar.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top