By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,330 Members | 1,438 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,330 IT Pros & Developers. It's quick & easy.

resource acquisition is initialization?

P: n/a
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.

I use g++ 3.2.3 on solaris 2.8, thanks.

yang

#include <string>
#include <iostream>

using namespace std;

class T {
private:
string name;

public:
T(const string& name) {
this->name = name;
cout<<"allocate resource for " << name << endl;
if( name.compare("banana") == 0 ) {
throw exception();
}
}

operator string() {
return name;
}

~T() {
cout<<"deallocate resource from " << name << endl;
}
};
class User {
private:
T t1, t2;

public:
User(const string& s, const string& p): t1(s), t2(p) {
cout<<"user inited" << endl;
try{
throw exception();
}catch(exception& e) {
}
}

void use( ) {
cout<< "use "<< (string)t1 << " and " << (string)t2 <<
endl;
throw exception();
}

~User() {
cout <<"user destroyed" << endl;
}
};
int main(int argc, char **argv) {
/*
User *u = NULL;
if( argc >= 3 ) {
if( argc > 3 ) {
User x(argv[1], argv[2]);
x.use();
return 0;
}
}
u = new User( argv[1], argv[2] );
}else{
u = new User(string("apple"), string("banana"));
}

u->use();
delete u;
*/
User u("apple", "banana");
u.use();
}
Jul 22 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
yang su wrote:
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.

I use g++ 3.2.3 on solaris 2.8, thanks.


Could be a bug in the compiler. I surrounded the contents of 'main'
with try {} catch(...) {} to prevent unhandled exception, and it worked
as expected under VC++ 7.1

Victor
Jul 22 '05 #2

P: n/a
yang su wrote:
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.


I think the problem is that you don't catch the exception. If an
uncaught exception is found, the process is terminated before the
variable can be destroyed. If I add a try/catch block in main around
the creation and usage of u, the object gets destroyed as expected.

Jul 22 '05 #3

P: n/a
yang su wrote:
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.


Not quite. t2 throws an exception for which no exception handler exist.
If something like that happens, the runtime system has to call the
terminate() function, which aborts the program. The fine point is: The
c++ standard says, that it is implementation defined, whether the stack
is unwound or not in this case!

So if you want guaranteed clean-up even in case of not-having an
appropriate exception handler, you'll have to wrap anything into a
catchall block:

int main()
try {
User u("apple", "banana");
u.use();
}
catch(...)
{
// call abort() or terminate() as you like..
}

Marco

Jul 22 '05 #4

P: n/a

"yang su" <y2*******@yahoo.com> wrote in message
news:16**************************@posting.google.c om...
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.

I use g++ 3.2.3 on solaris 2.8, thanks.

yang

[snip]

class User {
private:
T t1, t2;


It is not defined whether t1 or t2 is constructed first. Only if t1 is
constructed before t2 will an exception in t2 cause the destructor for t1 to
be called.

Try this

T t1;
T t2;

Now t1 must be constructed before t2.

john
Jul 22 '05 #5

P: n/a
John Harrison wrote:
class User {
private:
T t1, t2;


It is not defined whether t1 or t2 is constructed first.


That's wrong. t1 is constructed first.

Jul 22 '05 #6

P: n/a
Rolf Magnus wrote:
John Harrison wrote:
class User {
private:
T t1, t2;


It is not defined whether t1 or t2 is constructed first.


That's wrong. t1 is constructed first.


Hmm, ok. I'm not sure about that actually. You mean the order is not
defined because they are declared as T t1, t2; instead of T t1; T t2;?

Jul 22 '05 #7

P: n/a

"Rolf Magnus" <ra******@t-online.de> wrote in message
news:cf*************@news.t-online.com...
Rolf Magnus wrote:
John Harrison wrote:
class User {
private:
T t1, t2;
It is not defined whether t1 or t2 is constructed first.


That's wrong. t1 is constructed first.


Hmm, ok. I'm not sure about that actually. You mean the order is not
defined because they are declared as T t1, t2; instead of T t1; T t2;?


That's what I mean, but I'm relying on my sometimes faulty recollection.
I'll look it up later.

John
Jul 22 '05 #8

P: n/a
John Harrison wrote:
"yang su" <y2*******@yahoo.com> wrote in message
news:16**************************@posting.google.c om...
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.

I use g++ 3.2.3 on solaris 2.8, thanks.

yang
[snip]

class User {
private:
T t1, t2;

It is not defined whether t1 or t2 is constructed first.


Really? Care to elaborate or give a quote from the Standard? For some
reason I always thought that initialisation (construction) happens in the
order of declaration. Besides, in a declaration statement there is
a sequence point after every declarator.
Only if t1 is
constructed before t2 will an exception in t2 cause the destructor for t1 to
be called.

Try this

T t1;
T t2;

Now t1 must be constructed before t2.

john


I _really_ think there is no difference between

A a, b;

and

A a; A b;

It would be illogical to have them behave differently depending on where
the declaration happens.

V
Jul 22 '05 #9

P: n/a
>>> class User {
private:
T t1, t2;

It is not defined whether t1 or t2 is constructed first.


Really? Care to elaborate or give a quote from the Standard?


No, seems I was wrong. I can't think where I got the idea from.

john
Jul 22 '05 #10

P: n/a
y2*******@yahoo.com (yang su) wrote in message news:<16**************************@posting.google. com>...
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen. [snip] int main(int argc, char **argv) { [snip]
User u("apple", "banana");
u.use();
}


Wasn't this the expected behavior? I would bet that the object u would
not be destroyed (destructor called) since an exception was thrown
during its creation (construction). Isn't this the prescribed
behavior?

Marcelo Pinto.
Jul 22 '05 #11

P: n/a
Marcelo Pinto wrote:
y2*******@yahoo.com (yang su) wrote in message
news:<16**************************@posting.google. com>...
I have a very simple program listed below, which basically tries to
use resources but prevent from memory leak should exception occurs.
class T is the resource and class User is to use the resource, my
expectation is that when t2 fails, the destructor of t1 should be
called, which didn't happen.

[snip]
int main(int argc, char **argv) {

[snip]

User u("apple", "banana");
u.use();
}


Wasn't this the expected behavior? I would bet that the object u would
not be destroyed (destructor called) since an exception was thrown
during its creation (construction). Isn't this the prescribed
behavior?


Each fully constructed object gets its destructor called, and u.t1 is
fully constructed at the point of the exception.

Jul 22 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.