473,698 Members | 2,034 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Exceptions & Constructors

The constructor in MyClass instantiates many objects pointers through
'new', I would like to implement a way to make sure that the object
has been allocated in memory by catch(ing) the bad_alloc exception
error, but this means that I have to throw this error back from
MyClass constructor, how can I avoid this?

Thanks folks!

Jul 30 '07
14 1606
On 30 Jul, 19:50, "Xavier Serrand" <xxxxxx.xxxx... @xxx.frwrote:
template <typename Tstatic Pile<T* createPile(int sz)
{
Pile<T* pp;
try
{
pp = new Pile<T>(sz);
return pp;
}
catch (std::bad_alloc &)
{
try
{
// clearing what can be cleared ...
// ...
// deleting the instance : the destructor has to be sure
// (may be hard to do...)
pp->~Pile<T>();
}
catch (std::exception & e)
{
// nothing to do
}
return NULL;
}
}
This is wrong isn't it? If bad_alloc is thrown then
the object won't have been constructed, so you don't
want to be calling the destructor on 'pp' - UB and
all that (not to mention the fact that pp is
uninitialised in this case anyway). In any case,
using new(nothrow) saves you having to mess about
with bad_alloc in the first place.

But as Alf has pointed out it's all largely academic,
if your program reaches this point you're probably
scuppered anyway, which reinforces my earlier
suggestion of keeping it simple and just letting the
exception propagate out of the ctor.
Jul 30 '07 #11

Erik Wikström wrote in message...
On 2007-07-30 13:15, ja******@gmail. com wrote:
The constructor in MyClass instantiates many objects pointers through
'new', I would like to implement a way to make sure that the object
has been allocated in memory by catch(ing) the bad_alloc exception
error, but this means that I have to throw this error back from
MyClass constructor, how can I avoid this?

Sure, add a flag to the class that tells if the object was constructed
correctly:

class Foo {
int* ptrarr[16];
public:
bool correct;
Foo() correct(true) {
try {
for (size_t i = 0; i < 16; ++i) ptrarr[i] = new int();
} catch(bad_alloc &){ correct = false; }
}
};

int main() {
Foo f;
if (f.correct == false) {
// Opps, failed to allocate
}
}
Re-worked for 'function-level try block' (just for an idea(OP)):

#include <stdexcept // #include <exception>
#include <new // bad_alloc
class Foo{
int *ptrarr[16];
public:
bool correct;
Foo() try : correct( true ) {

// yup, I found yer lost colon. <G>
// ( It was hangin' with a bad crowd at the Bar(). )
for (size_t i = 0; i < 16; ++i) ptrarr[i] = new int();
} catch( std::bad_alloc& ){
correct = false;
// delete what you new.
// throw;
} // catch
}; // class Foo

// or, the extreme: (not borland6)
#include <iostream // #include <ostream>
#include <stdexcept>
#include <new // bad_alloc

int main() try {
Foo f; // un-comment "throw;" in Foo's "catch()"
// throw "failure in main()"; // to test
} // main() end
catch( char const *msg) {
std::cout << msg << std::endl;
return 1;
}
catch( std::bad_alloc& ){
std::cout <<" Opps, failed to allocate!"<<std ::endl;
// throw;
return 1;
} // catch
catch( ... ){
std::cout <<" Unknown failure!"<<std: :endl;
return 1;
} // catch
Erik, I started to toss out this post[1], but, seeing other posts, it may
help somebody.

[1] - I only wanted to inform you I found your lost colon. :-}
Was that an "colon-oscopy"(sp?)?
[ corrections, comments welcome. ]
--
Bob R
POVrookie
Jul 30 '07 #12

"tragomaskhalos " <da************ *@logicacmg.com a écrit dans le message de
news:11******** **************@ q75g2000hsh.goo glegroups.com.. .
On 30 Jul, 19:50, "Xavier Serrand" <xxxxxx.xxxx... @xxx.frwrote:
template <typename Tstatic Pile<T* createPile(int sz)
{
Pile<T* pp;
try
{
pp = new Pile<T>(sz);
return pp;
}
catch (std::bad_alloc &)
{
try
{
// clearing what can be cleared ...
// ...
// deleting the instance : the destructor has to be sure
// (may be hard to do...)
pp->~Pile<T>();
}
catch (std::exception & e)
{
// nothing to do
}
return NULL;
}
}

This is wrong isn't it? If bad_alloc is thrown then
the object won't have been constructed, so you don't
want to be calling the destructor on 'pp' - UB and
all that (not to mention the fact that pp is
uninitialised in this case anyway). In any case,
using new(nothrow) saves you having to mess about
with bad_alloc in the first place.

But as Alf has pointed out it's all largely academic,
if your program reaches this point you're probably
scuppered anyway, which reinforces my earlier
suggestion of keeping it simple and just letting the
exception propagate out of the ctor.

object could hav been constructed and bad_alloc raised ... after if one or
more members are pointers
For exemple :
class Something {
....
char * m_s[nbr]; // allocated by one of the constructors
....

Something ()
{...}
Something (int sz)
{allocation of m_s...}

}
Jul 30 '07 #13
Xavier Serrand wrote:
>
"tragomaskhalos " <da************ *@logicacmg.com a écrit dans le message
de news:11******** **************@ q75g2000hsh.goo glegroups.com.. .
>On 30 Jul, 19:50, "Xavier Serrand" <xxxxxx.xxxx... @xxx.frwrote:
template <typename Tstatic Pile<T* createPile(int sz)
{
Pile<T* pp;
try
{
pp = new Pile<T>(sz);
return pp;
}
catch (std::bad_alloc &)
{
try
{
// clearing what can be cleared ...
// ...
// deleting the instance : the destructor has to be sure
// (may be hard to do...)
pp->~Pile<T>();
}
catch (std::exception & e)
{
// nothing to do
}
return NULL;
}
}

This is wrong isn't it? If bad_alloc is thrown then
the object won't have been constructed, so you don't
want to be calling the destructor on 'pp' - UB and
all that (not to mention the fact that pp is
uninitialise d in this case anyway). In any case,
using new(nothrow) saves you having to mess about
with bad_alloc in the first place.

But as Alf has pointed out it's all largely academic,
if your program reaches this point you're probably
scuppered anyway, which reinforces my earlier
suggestion of keeping it simple and just letting the
exception propagate out of the ctor.

object could hav been constructed and bad_alloc raised ... after if one or
more members are pointers
[snip]

No.

If during evaluation of the expression

new SomeType ( some args )

memory allocation is successful but the constructor call throws (whatever it
may throw) the call to new will not return, the memory will be deallocated
and not leak, and there will not be possible way to do manual clean up
afterwards. For example, in the code above, if

pp = new File<T>( sz )

throws from the call to File<T>, the variable pp will not point to anything
meaningful. In particular, pp->~File<T>() is undefined behavior.
The upshot is: you have to write the constructor for any class in such a way
that it does not leak when subobjects and members cannot be successfully
constructed. Outside the constructor, there is no way to undo the harm that
has been done. In the above example, if File<T>() could fail, it better
fail gracefully (without resource leak) because your proposed trick to
repair things from the outside is bound to fail.

Hint: within constructors, use std::auto_ptr for allocation of multiple
pointer members.

Best

Kai-Uwe Bux
Jul 31 '07 #14
On Jul 30, 11:10 pm, tragomaskhalos <dave.du.verg.. .@logicacmg.com >
wrote:
On 30 Jul, 19:50, "Xavier Serrand" <xxxxxx.xxxx... @xxx.frwrote:
template <typename Tstatic Pile<T* createPile(int sz)
{
Pile<T* pp;
try
{
pp = new Pile<T>(sz);
return pp;
}
catch (std::bad_alloc &)
{
try
{
// clearing what can be cleared ...
// ...
// deleting the instance : the destructor has to be sure
// (may be hard to do...)
pp->~Pile<T>();
}
catch (std::exception & e)
{
// nothing to do
}
return NULL;
}
}
This is wrong isn't it? If bad_alloc is thrown then
the object won't have been constructed, so you don't
want to be calling the destructor on 'pp' - UB and
all that (not to mention the fact that pp is
uninitialised in this case anyway). In any case,
using new(nothrow) saves you having to mess about
with bad_alloc in the first place.
But as Alf has pointed out it's all largely academic,
if your program reaches this point you're probably
scuppered anyway, which reinforces my earlier
suggestion of keeping it simple and just letting the
exception propagate out of the ctor.
The problem is that Alf's point doesn't always apply. It
certainly doesn't apply on smaller, embedded systems, which
don't have much memory. And it may not always apply on larger,
general purpose systems: when, for example, the allocations are
due to a particularly complicated user request, it may make
sense to catch bad_alloc at a higher level, and report some sort
of error without bringing down the server. (A lot of protocols
provide for an "insufficie nt resources" error, for example, if
the request is too complicated.)

The real problem if you do want to recover is that you have to
ensure that all of the memory you've already allocated is freed.
The usual answer to this problem is "one pointer per class". A
class which needs a lot of pointers actually uses a lot of
smaller classes. And when bad_alloc (or any other exception)
pops up, the destructors for all of the already constructed
sub-objects are called, freeing the pointers. (Note that the
"smaller classes" can be as simple as boost::scoped_p tr or
std::auto_ptr; if the pointers are in a standard container,
something like boost::shared_p tr may be appropriate, or wrapping
the standard container in a special class---violating the
principle of one pointer per class, but in this case, it works,
because there won't be any uninitialized pointers, ever.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 31 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
1389
by: John | last post by:
Hi, In my years as a VB programmer, I have settled into this pattern of creating collections classes, with an AddNew() method. AddNew() validates the parameters, instantiates the object, adds it to the collection, and returns it. The AddNew() method was used to get around the lack of a constructor in VB classes. Now I was just about to rewrite this same pattern in C#, when I realized hey ... I've got constructors, and instead of...
8
3590
by: Shane Groff | last post by:
I know this is a recurring discussion (I've spent the last 3 days reading through threads on the topic), but I feel compelled to start it up again. After reading through the existing threads, I find myself convinced that exceptions are a better mechanism, for example because constructors and operators can't return errors, and code that doesn't need to handle/translate/recover in the face of errors, but can just propagate the error is...
10
1776
by: Brian Folke Seaberg | last post by:
I was recently browsing a couple of C++ books at the local bookstore. One book called throwing exceptions from constructors a "dubious practice." Another book recommended not throwing exceptions from constructors due to the fact that the destructor for the object being constructed will not be executed and that as a result any resources allocated by the constructor prior to throwing the exception will not be deallocated if the...
21
4429
by: mihai | last post by:
People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object. What about copy constructors? How can we avoid throwing exceptions? If we already have an abject witch was initialized wit _create_ we will be forced to call create in copy constructor and to throw exceptions from it. Have a nice day,
4
2376
by: KC | last post by:
Greeting all! I have a problem that I'm hoping will be of interest to others here, and maybe a solution will crop up. I appoligize for the message's length. Now, I'm new to C# and .NET, so I am developing an application during my learning phase. Because of this, I'm trying to use as many *features* as is reasonable. Some may be more reasonable than others :) Keep that in mind. OK, basicaly my problem is how to handle exceptions in...
16
2166
by: Einar Høst | last post by:
Hi, I'm getting into the Trace-functionality in .NET, using it to provide some much-needed logging across dlls in the project we're working on. However, being a newbie, I'm wondering if some more experienced loggers can provide me with some ideas as to how to log in a simple yet flexible manner. For instance, I'd like the code to be as uncluttered as possible by Trace statements. As an example of basic logging functionality, I've come...
5
1885
by: tryptik | last post by:
All- I have heard differing points of view on whether or not constructors should throw. I am working on a library, and I need to know if it is bad form for a consturctor to throw. Thanks -J
24
4934
by: usenet | last post by:
I am unable to catch floating exceptions (e.g. divide by 0 or 0/0) using the standard exceptions defined in stdexcept. What is the recommended way to catch such exceptions? Thanks, Song
0
8600
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9155
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8890
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6517
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5859
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4360
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4614
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3038
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2322
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.