Repeated destructor calls and tracking handles in C++/CLI - c++

I'm playing around with C++/CLI, using the MSDN documentation and the ECMA standard, and Visual C++ Express 2010. What struck me was the following departure from C++:
For ref classes, both the finalizer and destructor must be written so they can be executed multiple times and on objects that have not been fully constructed.
I concocted a little example:
#include <iostream>
ref struct Foo
{
Foo() { std::wcout << L"Foo()\n"; }
~Foo() { std::wcout << L"~Foo()\n"; this->!Foo(); }
!Foo() { std::wcout << L"!Foo()\n"; }
};
int main()
{
Foo ^ r;
{
Foo x;
r = %x;
} // #1
delete r; // #2
}
At the end of the block at #1, the automatic variable xdies, and the destructor is called (which in turn calls the finalizer explicitly, as is the usual idiom). This is all fine and well. But then I delete the object again through the reference r! The output is this:
Foo()
~Foo()
!Foo()
~Foo()
!Foo()
Questions:
Is it undefined behavior, or is it entirely acceptable, to call delete r on line #2?
If we remove line #2, does it matter that r is still a tracking handle for an object that (in the sense of C++) no longer exists? Is it a "dangling handle"? Does its reference counting entail that there will be an attempted double deletion?
I know that there isn't an actual double deletion, as the output becomes this:
Foo()
~Foo()
!Foo()
However, I'm not sure whether that's a happy accident or guaranteed to be well-defined behaviour.
Under which other circumstances can the destructor of a managed object be called more than once?
Would it be OK to insert x.~Foo(); immediately before or after r = %x;?
In other words, do managed objects "live forever" and can have both their destructors and their finalizers called over and over again?
In response to #Hans's demand for a non-trivial class, you may also consider this version (with destructor and finalizer made to conform to the multiple-call requirement):
ref struct Foo
{
Foo()
: p(new int[10])
, a(gcnew cli::array<int>(10))
{
std::wcout << L"Foo()\n";
}
~Foo()
{
delete a;
a = nullptr;
std::wcout << L"~Foo()\n";
this->!Foo();
}
!Foo()
{
delete [] p;
p = nullptr;
std::wcout << L"!Foo()\n";
}
private:
int * p;
cli::array<int> ^ a;
};

I'll just try to address the issues you bring up in order:
For ref classes, both the finalizer and destructor must be written so they can be executed multiple times and on objects that have not been fully constructed.
The destructor ~Foo() simply auto-generates two methods, an implementation of the IDisposable::Dispose() method as well as a protected Foo::Dispose(bool) method which implements the disposable pattern. These are plain methods and therefore may be invoked multiple times. It is permitted in C++/CLI to call the finalizer directly, this->!Foo() and is commonly done, just like you did. The garbage collector only ever calls the finalizer once, it keeps track internally whether or not that was done. Given that calling the finalizer directly is permitted and that calling Dispose() multiple times is allowed, it is thus possible to run the finalizer code more than once. This is specific to C++/CLI, other managed languages don't allow it. You can easily prevent it, a nullptr check usually gets the job done.
Is it undefined behavior, or is it entirely acceptable, to call delete r on line #2?
It is not UB and entirely acceptable. The delete operator simply calls the IDisposable::Dispose() method and thus runs your destructor. What you do inside it, very typically calling the destructor of an unmanaged class, may well invoke UB.
If we remove line #2, does it matter that r is still a tracking handle
No. Invoking the destructor is entirely optional without a good way to enforce it. Nothing goes wrong, the finalizer ultimately will always run. In the given example that will happen when the CLR runs the finalizer thread one last time before shutting down. The only side effect is that the program runs "heavy", holding on to resources longer than necessary.
Under which other circumstances can the destructor of a managed object be called more than once?
It's pretty common, an overzealous C# programmer may well call your Dispose() method more than once. Classes that provide both a Close and a Dispose method are pretty common in the framework. There are some patterns where it is nearly unavoidable, the case where another class assumes ownership of an object. The standard example is this bit of C# code:
using (var fs = new FileStream(...))
using (var sw = new StreamWriter(fs)) {
// Write file...
}
The StreamWriter object will take ownership of its base stream and call its Dispose() method at the last curly brace. The using statement on FileStream object calls Dispose() a second time. Writing this code so that this doesn't happen and still provide exception guarantees is too difficult. Specifying that Dispose() may be called more than once solves the problem.
Would it be OK to insert x.~Foo(); immediately before or after r = %x;?
It's okay. The outcome is unlikely to be pleasant, a NullReferenceException would be the most likely result. This is something that you should test for, raise an ObjectDisposedException to give the programmer a better diagnostic. All standard .NET framework classes do so.
In other words, do managed objects "live forever"
No, the garbage collector declares the object dead, and collects it, when it cannot find any references to the object anymore. This is a fail-safe way to memory management, there is no way to accidentally reference a deleted object. Because doing so requires a reference, one that the GC will always see. Common memory management problems like circular references are not an issue either.
Code snippet
Deleting the a object is unnecessary and has no effect. You only delete objects that implement IDisposable, an array does not do so. The common rule is that a .NET class only implements IDisposable when it manages resources other than memory. Or if it has a field of a class type that itself implements IDisposable.
It is furthermore questionable whether you should implement a destructor in this case. Your example class is holding on to a rather modest unmanaged resource. By implementing the destructor, you impose the burden on the client code to use it. It strongly depends on the class usage how easy it is for the client programmer to do so, it definitely is not if the object is expected to live for a long time, beyond the body of a method so that the using statement isn't usable. You can let the garbage collector know about memory consumption that it cannot track, call GC::AddMemoryPressure(). Which also takes care of the case where the client programmer simply doesn't use Dispose() because it is too hard.

Guidelines from standard C++ still apply:
Calling delete on an automatic variable, or one that's already been cleaned up, is still a bad idea.
It's a tracking pointer to a disposed object. Dereferencing such is a bad idea. With garbage collection, the memory is kept around as long as any non-weak reference exists, so you can't access the wrong object by accident, but you still can't use this disposed object in any useful way, since its invariants probably no longer hold.
Multiple destruction can only happen on managed objects when your code is written in really bad style that would have been UB in standard C++ (see 1 above and 4 below).
Explicitly calling the destructor on an automatic variable, then not creating a new one in its place for the automatic destruction call to find, is still a bad idea.
In general, you think think of object lifetime as separate from memory allocation (just like standard C++ does). Garbage collection is used to manage deallocation -- so the memory is still there -- but the object is dead. Unlike standard C++, you can't go and reuse that memory for raw byte storage, because parts of the .NET runtime may assume the metadata is still valid.
Neither the garbage collector nor "stack semantics" (automatic variable syntax) use reference counting.
(Ugly details: disposing an object doesn't break the .NET runtime's own invariants concerning that object, so you can probably even still use it as a threading monitor. But that just makes an ugly hard-to-understand design, so please don't.)

Related

Runtime error on calling a function after deletion of 'this' pointer [duplicate]

Is it allowed to delete this; if the delete-statement is the last statement that will be executed on that instance of the class? Of course I'm sure that the object represented by the this-pointer is newly-created.
I'm thinking about something like this:
void SomeModule::doStuff()
{
// in the controller, "this" object of SomeModule is the "current module"
// now, if I want to switch over to a new Module, eg:
controller->setWorkingModule(new OtherModule());
// since the new "OtherModule" object will take the lead,
// I want to get rid of this "SomeModule" object:
delete this;
}
Can I do this?
The C++ FAQ Lite has a entry specifically for this
https://isocpp.org/wiki/faq/freestore-mgmt#delete-this
I think this quote sums it up nicely
As long as you're careful, it's OK for an object to commit suicide (delete this).
Yes, delete this; has defined results, as long as (as you've noted) you assure the object was allocated dynamically, and (of course) never attempt to use the object after it's destroyed. Over the years, many questions have been asked about what the standard says specifically about delete this;, as opposed to deleting some other pointer. The answer to that is fairly short and simple: it doesn't say much of anything. It just says that delete's operand must be an expression that designates a pointer to an object, or an array of objects. It goes into quite a bit of detail about things like how it figures out what (if any) deallocation function to call to release the memory, but the entire section on delete (§[expr.delete]) doesn't mention delete this; specifically at all. The section on destructors does mention delete this in one place (§[class.dtor]/13):
At the point of definition of a virtual destructor (including an implicit definition (15.8)), the non-array deallocation function is determined as if for the expression delete this appearing in a non-virtual destructor of the destructor’s class (see 8.3.5).
That tends to support the idea that the standard considers delete this; to be valid -- if it was invalid, its type wouldn't be meaningful. That's the only place the standard mentions delete this; at all, as far as I know.
Anyway, some consider delete this a nasty hack, and tell anybody who will listen that it should be avoided. One commonly cited problem is the difficulty of ensuring that objects of the class are only ever allocated dynamically. Others consider it a perfectly reasonable idiom, and use it all the time. Personally, I'm somewhere in the middle: I rarely use it, but don't hesitate to do so when it seems to be the right tool for the job.
The primary time you use this technique is with an object that has a life that's almost entirely its own. One example James Kanze has cited was a billing/tracking system he worked on for a phone company. When you start to make a phone call, something takes note of that and creates a phone_call object. From that point onward, the phone_call object handles the details of the phone call (making a connection when you dial, adding an entry to the database to say when the call started, possibly connect more people if you do a conference call, etc.) When the last people on the call hang up, the phone_call object does its final book-keeping (e.g., adds an entry to the database to say when you hung up, so they can compute how long your call was) and then destroys itself. The lifetime of the phone_call object is based on when the first person starts the call and when the last people leave the call -- from the viewpoint of the rest of the system, it's basically entirely arbitrary, so you can't tie it to any lexical scope in the code, or anything on that order.
For anybody who might care about how dependable this kind of coding can be: if you make a phone call to, from, or through almost any part of Europe, there's a pretty good chance that it's being handled (at least in part) by code that does exactly this.
If it scares you, there's a perfectly legal hack:
void myclass::delete_me()
{
std::unique_ptr<myclass> bye_bye(this);
}
I think delete this is idiomatic C++ though, and I only present this as a curiosity.
There is a case where this construct is actually useful - you can delete the object after throwing an exception that needs member data from the object. The object remains valid until after the throw takes place.
void myclass::throw_error()
{
std::unique_ptr<myclass> bye_bye(this);
throw std::runtime_exception(this->error_msg);
}
Note: if you're using a compiler older than C++11 you can use std::auto_ptr instead of std::unique_ptr, it will do the same thing.
One of the reasons that C++ was designed was to make it easy to reuse code. In general, C++ should be written so that it works whether the class is instantiated on the heap, in an array, or on the stack. "Delete this" is a very bad coding practice because it will only work if a single instance is defined on the heap; and there had better not be another delete statement, which is typically used by most developers to clean up the heap. Doing this also assumes that no maintenance programmer in the future will cure a falsely perceived memory leak by adding a delete statement.
Even if you know in advance that your current plan is to only allocate a single instance on the heap, what if some happy-go-lucky developer comes along in the future and decides to create an instance on the stack? Or, what if he cuts and pastes certain portions of the class to a new class that he intends to use on the stack? When the code reaches "delete this" it will go off and delete it, but then when the object goes out of scope, it will call the destructor. The destructor will then try to delete it again and then you are hosed. In the past, doing something like this would screw up not only the program but the operating system and the computer would need to be rebooted. In any case, this is highly NOT recommended and should almost always be avoided. I would have to be desperate, seriously plastered, or really hate the company I worked for to write code that did this.
It is allowed (just do not use the object after that), but I wouldn't write such code on practice. I think that delete this should appear only in functions that called release or Release and looks like: void release() { ref--; if (ref<1) delete this; }.
Well, in Component Object Model (COM) delete this construction can be a part of Release method that is called whenever you want to release aquisited object:
void IMyInterface::Release()
{
--instanceCount;
if(instanceCount == 0)
delete this;
}
This is the core idiom for reference-counted objects.
Reference-counting is a strong form of deterministic garbage collection- it ensures objects manage their OWN lifetime instead of relying on 'smart' pointers, etc. to do it for them. The underlying object is only ever accessed via "Reference" smart pointers, designed so that the pointers increment and decrement a member integer (the reference count) in the actual object.
When the last reference drops off the stack or is deleted, the reference count will go to zero. Your object's default behavior will then be a call to "delete this" to garbage collect- the libraries I write provide a protected virtual "CountIsZero" call in the base class so that you can override this behavior for things like caching.
The key to making this safe is not allowing users access to the CONSTRUCTOR of the object in question (make it protected), but instead making them call some static member- the FACTORY- like "static Reference CreateT(...)". That way you KNOW for sure that they're always built with ordinary "new" and that no raw pointer is ever available, so "delete this" won't ever blow up.
You can do so. However, you can't assign to this. Thus the reason you state for doing this, "I want to change the view," seems very questionable. The better method, in my opinion, would be for the object that holds the view to replace that view.
Of course, you're using RAII objects and so you don't actually need to call delete at all...right?
This is an old, answered, question, but #Alexandre asked "Why would anyone want to do this?", and I thought that I might provide an example usage that I am considering this afternoon.
Legacy code. Uses naked pointers Obj*obj with a delete obj at the end.
Unfortunately I need sometimes, not often, to keep the object alive longer.
I am considering making it a reference counted smart pointer. But there would be lots of code to change, if I was to use ref_cnt_ptr<Obj> everywhere. And if you mix naked Obj* and ref_cnt_ptr, you can get the object implicitly deleted when the last ref_cnt_ptr goes away, even though there are Obj* still alive.
So I am thinking about creating an explicit_delete_ref_cnt_ptr. I.e. a reference counted pointer where the delete is only done in an explicit delete routine. Using it in the one place where the existing code knows the lifetime of the object, as well as in my new code that keeps the object alive longer.
Incrementing and decrementing the reference count as explicit_delete_ref_cnt_ptr get manipulated.
But NOT freeing when the reference count is seen to be zero in the explicit_delete_ref_cnt_ptr destructor.
Only freeing when the reference count is seen to be zero in an explicit delete-like operation. E.g. in something like:
template<typename T> class explicit_delete_ref_cnt_ptr {
private:
T* ptr;
int rc;
...
public:
void delete_if_rc0() {
if( this->ptr ) {
this->rc--;
if( this->rc == 0 ) {
delete this->ptr;
}
this->ptr = 0;
}
}
};
OK, something like that. It's a bit unusual to have a reference counted pointer type not automatically delete the object pointed to in the rc'ed ptr destructor. But it seems like this might make mixing naked pointers and rc'ed pointers a bit safer.
But so far no need for delete this.
But then it occurred to me: if the object pointed to, the pointee, knows that it is being reference counted, e.g. if the count is inside the object (or in some other table), then the routine delete_if_rc0 could be a method of the pointee object, not the (smart) pointer.
class Pointee {
private:
int rc;
...
public:
void delete_if_rc0() {
this->rc--;
if( this->rc == 0 ) {
delete this;
}
}
}
};
Actually, it doesn't need to be a member method at all, but could be a free function:
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
void* tptr = (void*)ptr;
if( keepalive_map[tptr] == 1 ) {
delete ptr;
}
};
(BTW, I know the code is not quite right - it becomes less readable if I add all the details, so I am leaving it like this.)
Delete this is legal as long as object is in heap.
You would need to require object to be heap only.
The only way to do that is to make the destructor protected - this way delete may be called ONLY from class , so you would need a method that would ensure deletion

Does the C++ standard allow/forbid deleting an object while its method is running? [duplicate]

Is it allowed to delete this; if the delete-statement is the last statement that will be executed on that instance of the class? Of course I'm sure that the object represented by the this-pointer is newly-created.
I'm thinking about something like this:
void SomeModule::doStuff()
{
// in the controller, "this" object of SomeModule is the "current module"
// now, if I want to switch over to a new Module, eg:
controller->setWorkingModule(new OtherModule());
// since the new "OtherModule" object will take the lead,
// I want to get rid of this "SomeModule" object:
delete this;
}
Can I do this?
The C++ FAQ Lite has a entry specifically for this
https://isocpp.org/wiki/faq/freestore-mgmt#delete-this
I think this quote sums it up nicely
As long as you're careful, it's OK for an object to commit suicide (delete this).
Yes, delete this; has defined results, as long as (as you've noted) you assure the object was allocated dynamically, and (of course) never attempt to use the object after it's destroyed. Over the years, many questions have been asked about what the standard says specifically about delete this;, as opposed to deleting some other pointer. The answer to that is fairly short and simple: it doesn't say much of anything. It just says that delete's operand must be an expression that designates a pointer to an object, or an array of objects. It goes into quite a bit of detail about things like how it figures out what (if any) deallocation function to call to release the memory, but the entire section on delete (§[expr.delete]) doesn't mention delete this; specifically at all. The section on destructors does mention delete this in one place (§[class.dtor]/13):
At the point of definition of a virtual destructor (including an implicit definition (15.8)), the non-array deallocation function is determined as if for the expression delete this appearing in a non-virtual destructor of the destructor’s class (see 8.3.5).
That tends to support the idea that the standard considers delete this; to be valid -- if it was invalid, its type wouldn't be meaningful. That's the only place the standard mentions delete this; at all, as far as I know.
Anyway, some consider delete this a nasty hack, and tell anybody who will listen that it should be avoided. One commonly cited problem is the difficulty of ensuring that objects of the class are only ever allocated dynamically. Others consider it a perfectly reasonable idiom, and use it all the time. Personally, I'm somewhere in the middle: I rarely use it, but don't hesitate to do so when it seems to be the right tool for the job.
The primary time you use this technique is with an object that has a life that's almost entirely its own. One example James Kanze has cited was a billing/tracking system he worked on for a phone company. When you start to make a phone call, something takes note of that and creates a phone_call object. From that point onward, the phone_call object handles the details of the phone call (making a connection when you dial, adding an entry to the database to say when the call started, possibly connect more people if you do a conference call, etc.) When the last people on the call hang up, the phone_call object does its final book-keeping (e.g., adds an entry to the database to say when you hung up, so they can compute how long your call was) and then destroys itself. The lifetime of the phone_call object is based on when the first person starts the call and when the last people leave the call -- from the viewpoint of the rest of the system, it's basically entirely arbitrary, so you can't tie it to any lexical scope in the code, or anything on that order.
For anybody who might care about how dependable this kind of coding can be: if you make a phone call to, from, or through almost any part of Europe, there's a pretty good chance that it's being handled (at least in part) by code that does exactly this.
If it scares you, there's a perfectly legal hack:
void myclass::delete_me()
{
std::unique_ptr<myclass> bye_bye(this);
}
I think delete this is idiomatic C++ though, and I only present this as a curiosity.
There is a case where this construct is actually useful - you can delete the object after throwing an exception that needs member data from the object. The object remains valid until after the throw takes place.
void myclass::throw_error()
{
std::unique_ptr<myclass> bye_bye(this);
throw std::runtime_exception(this->error_msg);
}
Note: if you're using a compiler older than C++11 you can use std::auto_ptr instead of std::unique_ptr, it will do the same thing.
One of the reasons that C++ was designed was to make it easy to reuse code. In general, C++ should be written so that it works whether the class is instantiated on the heap, in an array, or on the stack. "Delete this" is a very bad coding practice because it will only work if a single instance is defined on the heap; and there had better not be another delete statement, which is typically used by most developers to clean up the heap. Doing this also assumes that no maintenance programmer in the future will cure a falsely perceived memory leak by adding a delete statement.
Even if you know in advance that your current plan is to only allocate a single instance on the heap, what if some happy-go-lucky developer comes along in the future and decides to create an instance on the stack? Or, what if he cuts and pastes certain portions of the class to a new class that he intends to use on the stack? When the code reaches "delete this" it will go off and delete it, but then when the object goes out of scope, it will call the destructor. The destructor will then try to delete it again and then you are hosed. In the past, doing something like this would screw up not only the program but the operating system and the computer would need to be rebooted. In any case, this is highly NOT recommended and should almost always be avoided. I would have to be desperate, seriously plastered, or really hate the company I worked for to write code that did this.
It is allowed (just do not use the object after that), but I wouldn't write such code on practice. I think that delete this should appear only in functions that called release or Release and looks like: void release() { ref--; if (ref<1) delete this; }.
Well, in Component Object Model (COM) delete this construction can be a part of Release method that is called whenever you want to release aquisited object:
void IMyInterface::Release()
{
--instanceCount;
if(instanceCount == 0)
delete this;
}
This is the core idiom for reference-counted objects.
Reference-counting is a strong form of deterministic garbage collection- it ensures objects manage their OWN lifetime instead of relying on 'smart' pointers, etc. to do it for them. The underlying object is only ever accessed via "Reference" smart pointers, designed so that the pointers increment and decrement a member integer (the reference count) in the actual object.
When the last reference drops off the stack or is deleted, the reference count will go to zero. Your object's default behavior will then be a call to "delete this" to garbage collect- the libraries I write provide a protected virtual "CountIsZero" call in the base class so that you can override this behavior for things like caching.
The key to making this safe is not allowing users access to the CONSTRUCTOR of the object in question (make it protected), but instead making them call some static member- the FACTORY- like "static Reference CreateT(...)". That way you KNOW for sure that they're always built with ordinary "new" and that no raw pointer is ever available, so "delete this" won't ever blow up.
You can do so. However, you can't assign to this. Thus the reason you state for doing this, "I want to change the view," seems very questionable. The better method, in my opinion, would be for the object that holds the view to replace that view.
Of course, you're using RAII objects and so you don't actually need to call delete at all...right?
This is an old, answered, question, but #Alexandre asked "Why would anyone want to do this?", and I thought that I might provide an example usage that I am considering this afternoon.
Legacy code. Uses naked pointers Obj*obj with a delete obj at the end.
Unfortunately I need sometimes, not often, to keep the object alive longer.
I am considering making it a reference counted smart pointer. But there would be lots of code to change, if I was to use ref_cnt_ptr<Obj> everywhere. And if you mix naked Obj* and ref_cnt_ptr, you can get the object implicitly deleted when the last ref_cnt_ptr goes away, even though there are Obj* still alive.
So I am thinking about creating an explicit_delete_ref_cnt_ptr. I.e. a reference counted pointer where the delete is only done in an explicit delete routine. Using it in the one place where the existing code knows the lifetime of the object, as well as in my new code that keeps the object alive longer.
Incrementing and decrementing the reference count as explicit_delete_ref_cnt_ptr get manipulated.
But NOT freeing when the reference count is seen to be zero in the explicit_delete_ref_cnt_ptr destructor.
Only freeing when the reference count is seen to be zero in an explicit delete-like operation. E.g. in something like:
template<typename T> class explicit_delete_ref_cnt_ptr {
private:
T* ptr;
int rc;
...
public:
void delete_if_rc0() {
if( this->ptr ) {
this->rc--;
if( this->rc == 0 ) {
delete this->ptr;
}
this->ptr = 0;
}
}
};
OK, something like that. It's a bit unusual to have a reference counted pointer type not automatically delete the object pointed to in the rc'ed ptr destructor. But it seems like this might make mixing naked pointers and rc'ed pointers a bit safer.
But so far no need for delete this.
But then it occurred to me: if the object pointed to, the pointee, knows that it is being reference counted, e.g. if the count is inside the object (or in some other table), then the routine delete_if_rc0 could be a method of the pointee object, not the (smart) pointer.
class Pointee {
private:
int rc;
...
public:
void delete_if_rc0() {
this->rc--;
if( this->rc == 0 ) {
delete this;
}
}
}
};
Actually, it doesn't need to be a member method at all, but could be a free function:
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
void* tptr = (void*)ptr;
if( keepalive_map[tptr] == 1 ) {
delete ptr;
}
};
(BTW, I know the code is not quite right - it becomes less readable if I add all the details, so I am leaving it like this.)
Delete this is legal as long as object is in heap.
You would need to require object to be heap only.
The only way to do that is to make the destructor protected - this way delete may be called ONLY from class , so you would need a method that would ensure deletion

How to force boehm gc collect all, right before a program exit

I'm learning boehm gc c++ interface now. Not working with it, just curious about. And I follow the official example, writing my classes what could be GCed, in destructor, there is a output, so I can tell whether an instance is GCed or not.
But only if I use a loop to create instances as many as something like a thousand or more could ever trigger a gc collection. If the code is simple like this:
class test_gc : public gc
{
public:
~test_gc()
{
cout << "~test_gc()" << endl;
}
};
int main()
{
GC_INIT();
::new (GC) test_gc();
GC_gcollect();
return 0;
}
it seems like the destructor is never called. There is no "~test_gc()" outputed. Also the optimization of the compiler is turned off.
I did some google, find nearly nothing but the official example.
Please help me how to force a gc collection before a program exit, or tell me how to use it in a correct way if I use it wrong.
Many thanks.
I did some google, find nearly nothing but the official example.
This Dr.Dobb's article on The Boehm Collector for C and C++ has some great examples.
it seems like the destructor is never called.
To quote the article:
but if you want the destructor to be called, you must delete the object yourself.
From the article #Shafik's linked to:
If you need a new class with destructors that the Boehm collector calls automatically, you may subclass the Boehm collector's class gc_cleanup. It's like class gc except that it arranges for the Boehm collector to call the destructor immediately before recycling an instance's memory. Remember that you have no guarantee that all instances will be recycled.
The problem is that Boehm's collector is conservative -- it doesn't know what values are live pointers and what values are not, so it scans everything that might be live and treats it as if it was. In your case, since you just called new immediately before GC_collect, its likely there's a pointer to the object in a register or on the stack somewhere that is making the collector think that it is still alive. Try putting the new in some other function called from main, so its frame will be popped before calling GC_collect:
int func()
{
::new (GC) test_gc();
return 0; /* overwrite the return value register so it doesn't contain the return value from ::new */
}
int main()
{
GC_INIT();
func();
GC_gcollect();
return 0;
}
This makes it more likely there won't be stray pointers to the object stored somewhere, but there are no guarentees.

delete this & private destructor

I've been thinking about the possible use of delete this in c++, and I've seen one use.
Because you can say delete this only when an object is on heap, I can make the destructor private and stop objects from being created on stack altogether. In the end I can just delete the object on heap by saying delete this in a random public member function that acts as a destructor. My questions:
1) Why would I want to force the object to be made on the heap instead of on the stack?
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Any scheme that uses delete this is somewhat dangerous, since whoever called the function that does that is left with a dangling pointer. (Of course, that's also the case when you delete an object normally, but in that case, it's clear that the object has been deleted). Nevertheless, there are somewhat legitimate cases for wanting an object to manage its own lifetime.
It could be used to implement a nasty, intrusive reference-counting scheme. You would have functions to "acquire" a reference to the object, preventing it from being deleted, and then "release" it once you've finished, deleting it if noone else has acquired it, along the lines of:
class Nasty {
public:
Nasty() : references(1) {}
void acquire() {
++references;
}
void release() {
if (--references == 0) {
delete this;
}
}
private:
~Nasty() {}
size_t references;
};
// Usage
Nasty * nasty = new Nasty; // 1 reference
nasty->acquire(); // get a second reference
nasty->release(); // back to one
nasty->release(); // deleted
nasty->acquire(); // BOOM!
I would prefer to use std::shared_ptr for this purpose, since it's thread-safe, exception-safe, works for any type without needing any explicit support, and prevents access after deleting.
More usefully, it could be used in an event-driven system, where objects are created, and then manage themselves until they receive an event that tells them that they're no longer needed:
class Worker : EventReceiver {
public:
Worker() {
start_receiving_events(this);
}
virtual void on(WorkEvent) {
do_work();
}
virtual void on(DeleteEvent) {
stop_receiving_events(this);
delete this;
}
private:
~Worker() {}
void do_work();
};
1) Why would I want to force the object to be made on the heap instead of on the stack?
1) Because the object's lifetime is not logically tied to a scope (e.g., function body, etc.). Either because it must manage its own lifespan, or because it is inherently a shared object (and thus, its lifespan must be attached to those of its co-dependent objects). Some people here have pointed out some examples like event handlers, task objects (in a scheduler), and just general objects in a complex object hierarchy.
2) Because you want to control the exact location where code is executed for the allocation / deallocation and construction / destruction. The typical use-case here is that of cross-module code (spread across executables and DLLs (or .so files)). Because of issues of binary compatibility and separate heaps between modules, it is often a requirement that you strictly control in what module these allocation-construction operations happen. And that implies the use of heap-based objects only.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Well, your use-case is really just a "how-to" not a "why". Of course, if you are going to use a delete this; statement within a member function, then you must have controls in place to force all creations to occur with new (and in the same translation unit as the delete this; statement occurs). Not doing this would just be very very poor style and dangerous. But that doesn't address the "why" you would use this.
1) As others have pointed out, one legitimate use-case is where you have an object that can determine when its job is over and consequently destroy itself. For example, an event handler deleting itself when the event has been handled, a network communication object that deletes itself once the transaction it was appointed to do is over, or a task object in a scheduler deleting itself when the task is done. However, this leaves a big problem: signaling to the outside world that it no longer exists. That's why many have mentioned the "intrusive reference counting" scheme, which is one way to ensure that the object is only deleted when there are no more references to it. Another solution is to use a global (singleton-like) repository of "valid" objects, in which case any accesses to the object must go through a check in the repository and the object must also add/remove itself from the repository at the same time as it makes the new and delete this; calls (either as part of an overloaded new/delete, or alongside every new/delete calls).
However, there is a much simpler and less intrusive way to achieve the same behavior, albeit less economical. One can use a self-referencing shared_ptr scheme. As so:
class AutonomousObject {
private:
std::shared_ptr<AutonomousObject> m_shared_this;
protected:
AutonomousObject(/* some params */);
public:
virtual ~AutonomousObject() { };
template <typename... Args>
static std::weak_ptr<AutonomousObject> Create(Args&&... args) {
std::shared_ptr<AutonomousObject> result(new AutonomousObject(std::forward<Args>(args)...));
result->m_shared_this = result; // link the self-reference.
return result; // return a weak-pointer.
};
// this is the function called when the life-time should be terminated:
void OnTerminate() {
m_shared_this.reset( NULL ); // do not use reset(), but use reset( NULL ).
};
};
With the above (or some variations upon this crude example, depending on your needs), the object will be alive for as long as it deems necessary and that no-one else is using it. The weak-pointer mechanism serves as the proxy to query for the existence of the object, by possible outside users of the object. This scheme makes the object a bit heavier (has a shared-pointer in it) but it is easier and safer to implement. Of course, you have to make sure that the object eventually deletes itself, but that's a given in this kind of scenario.
2) The second use-case I can think of ties in to the second motivation for restricting an object to be heap-only (see above), however, it applies also for when you don't restrict it as such. If you want to make sure that both the deallocation and the destruction are dispatched to the correct module (the module from which the object was allocated and constructed), you must use a dynamic dispatching method. And for that, the easiest is to just use a virtual function. However, a virtual destructor is not going to cut it because it only dispatches the destruction, not the deallocation. The solution is to use a virtual "destroy" function that calls delete this; on the object in question. Here is a simple scheme to achieve this:
struct CrossModuleDeleter; //forward-declare.
class CrossModuleObject {
private:
virtual void Destroy() /* final */;
public:
CrossModuleObject(/* some params */); //constructor can be public.
virtual ~CrossModuleObject() { }; //destructor can be public.
//.... whatever...
friend struct CrossModuleDeleter;
template <typename... Args>
static std::shared_ptr< CrossModuleObject > Create(Args&&... args);
};
struct CrossModuleDeleter {
void operator()(CrossModuleObject* p) const {
p->Destroy(); // do a virtual dispatch to reach the correct deallocator.
};
};
// In the cpp file:
// Note: This function should not be inlined, so stash it into a cpp file.
void CrossModuleObject::Destroy() {
delete this;
};
template <typename... Args>
std::shared_ptr< CrossModuleObject > CrossModuleObject::Create(Args&&... args) {
return std::shared_ptr< CrossModuleObject >( new CrossModuleObject(std::forward<Args>(args)...), CrossModuleDeleter() );
};
The above kind of scheme works well in practice, and it has the nice advantage that the class can act as a base-class with no additional intrusion by this virtual-destroy mechanism in the derived classes. And, you can also modify it for the purpose of allowing only heap-based objects (as usually, making constructors-destructors private or protected). Without the heap-based restriction, the advantage is that you can still use the object as a local variable or data member (by value) if you want, but, of course, there will be loop-holes left to avoid by whoever uses the class.
As far as I know, these are the only legitimate use-cases I have ever seen anywhere or heard of (and the first one is easily avoidable, as I have shown, and often should be).
The general reason is that the lifetime of the object is determined by some factor internal to the class, at least from an application viewpoint. Hence, it may very well be a private method which calls delete this;.
Obviously, when the object is the only one to know how long it's needed, you can't put it on a random thread stack. It's necessary to create such objects on the heap.
It's generally an exceptionally bad idea. There are a very few cases- for example, COM objects have enforced intrusive reference counting. You'd only ever do this with a very specific situational reason- never for a general-purpose class.
1) Why would I want to force the object to be made on the heap instead of on the stack?
Because its life span isn't determined by the scoping rule.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
You use delete this when the object is the best placed one to be responsible for its own life span. One of the simplest example I know of is a window in a GUI. The window reacts to events, a subset of which means that the window has to be closed and thus deleted. In the event handler the window does a delete this. (You may delegate the handling to a controller class. But the situation "window forwards event to controller class which decides to delete the window" isn't much different of delete this, the window event handler will be left with the window deleted. You may also need to decouple the close from the delete, but your rationale won't be related to the desirability of delete this).
delete this;
can be useful at times and is usually used for a control class that also controls the lifetime of another object. With intrusive reference counting, the class it is controlling is one that derives from it.
The outcome of using such a class should be to make lifetime handling easier for users or creators of your class. If it doesn't achieve this, it is bad practice.
A legitimate example may be where you need a class to clean up all references to itself before it is destructed. In such a case, you "tell" the class whenever you are storing a reference to it (in your model, presumably) and then on exit, your class goes around nulling out these references or whatever before it calls delete this on itself.
This should all happen "behind the scenes" for users of your class.
"Why would I want to force the object to be made on the heap instead of on the stack?"
Generally when you force that it's not because you want to as such, it's because the class is part of some polymorphic hierarchy, and the only legitimate way to get one is from a factory function that returns an instance of a different derived class according to the parameters you pass it, or according to some configuration that it knows about. Then it's easy to arrange that the factory function creates them with new. There's no way that users of those classes could have them on the stack even if they wanted to, because they don't know in advance the derived type of the object they're using, only the base type.
Once you have objects like that, you know that they're destroyed with delete, and you can consider managing their lifecycle in a way that ultimately ends in delete this. You'd only do this if the object is somehow capable of knowing when it's no longer needed, which usually would be (as Mike says) because it's part of some framework that doesn't manage object lifetime explicitly, but does tell its components that they've been detached/deregistered/whatever[*].
If I remember correctly, James Kanze is your man for this. I may have misremembered, but I think he occasionally mentions that in his designs delete this isn't just used but is common. Such designs avoid shared ownership and external lifecycle management, in favour of networks of entity objects managing their own lifecycles. And where necessary, deregistering themselves from anything that knows about them prior to destroying themselves. So if you have several "tools" in a "toolbelt" then you wouldn't construe that as the toolbelt "owning" references to each of the tools, you think of the tools putting themselves in and out of the belt.
[*] Otherwise you'd have your factory return a unique_ptr or auto_ptr to encourage callers to stuff the object straight into the memory management type of their choice, or you'd return a raw pointer but provide the same encouragement via documentation. All the stuff you're used to seeing.
A good rule of thumb is not to use delete this.
Simply put, the thing that uses new should be responsible enough to use the delete when done with the object. This also avoids the problems with is on the stack/heap.
Once upon a time i was writing some plugin code. I believe i mixed build (debug for plugin, release for main code or maybe the other way around) because one part should be fast. Or maybe another situation happened. Such main is already released built on gcc and plugin is being debugged/tested on VC. When the main code deleted something from the plugin or plugin deleted something a memory issue would occur. It was because they both used different memory pools or malloc implementations. So i had a private dtor and a virtual function called deleteThis().
-edit- Now i may consider overloading the delete operator or using a smart pointer or simply just state never delete a function. It will depend and usually overloading new/delete should never be done unless you really know what your doing (dont do it). I decide to use deleteThis() because i found it easier then the C like way of thing_alloc and thing_free as deleteThis() felt like the more OOP way of doing it

Understanding the meaning of the term and the concept - RAII (Resource Acquisition is Initialization)

Could you C++ developers please give us a good description of what RAII is, why it is important, and whether or not it might have any relevance to other languages?
I do know a little bit. I believe it stands for "Resource Acquisition is Initialization". However, that name doesn't jive with my (possibly incorrect) understanding of what RAII is: I get the impression that RAII is a way of initializing objects on the stack such that, when those variables go out of scope, the destructors will automatically be called causing the resources to be cleaned up.
So why isn't that called "using the stack to trigger cleanup" (UTSTTC:)? How do you get from there to "RAII"?
And how can you make something on the stack that will cause the cleanup of something that lives on the heap? Also, are there cases where you can't use RAII? Do you ever find yourself wishing for garbage collection? At least a garbage collector you could use for some objects while letting others be managed?
Thanks.
So why isn't that called "using the stack to trigger cleanup" (UTSTTC:)?
RAII is telling you what to do: Acquire your resource in a constructor! I would add: one resource, one constructor. UTSTTC is just one application of that, RAII is much more.
Resource Management sucks. Here, resource is anything that needs cleanup after use. Studies of projects across many platforms show the majority of bugs are related to resource management - and it's particularly bad on Windows (due to the many types of objects and allocators).
In C++, resource management is particularly complicated due to the combination of exceptions and (C++ style) templates. For a peek under the hood, see GOTW8).
C++ guarantees that the destructor is called if and only if the constructor succeeded. Relying on that, RAII can solve many nasty problems the average programmer might not even be aware of. Here are a few examples beyond the "my local variables will be destroyed whenever I return".
Let us start with an overly simplistic FileHandle class employing RAII:
class FileHandle
{
FILE* file;
public:
explicit FileHandle(const char* name)
{
file = fopen(name);
if (!file)
{
throw "MAYDAY! MAYDAY";
}
}
~FileHandle()
{
// The only reason we are checking the file pointer for validity
// is because it might have been moved (see below).
// It is NOT needed to check against a failed constructor,
// because the destructor is NEVER executed when the constructor fails!
if (file)
{
fclose(file);
}
}
// The following technicalities can be skipped on the first read.
// They are not crucial to understanding the basic idea of RAII.
// However, if you plan to implement your own RAII classes,
// it is absolutely essential that you read on :)
// It does not make sense to copy a file handle,
// hence we disallow the otherwise implicitly generated copy operations.
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
// The following operations enable transfer of ownership
// and require compiler support for rvalue references, a C++0x feature.
// Essentially, a resource is "moved" from one object to another.
FileHandle(FileHandle&& that)
{
file = that.file;
that.file = 0;
}
FileHandle& operator=(FileHandle&& that)
{
file = that.file;
that.file = 0;
return *this;
}
}
If construction fails (with an exception), no other member function - not even the destructor - gets called.
RAII avoids using objects in an invalid state. it already makes life easier before we even use the object.
Now, let us have a look at temporary objects:
void CopyFileData(FileHandle source, FileHandle dest);
void Foo()
{
CopyFileData(FileHandle("C:\\source"), FileHandle("C:\\dest"));
}
There are three error cases to handled: no file can be opened, only one file can be opened, both files can be opened but copying the files failed. In a non-RAII implementation, Foo would have to handle all three cases explicitly.
RAII releases resources that were acquired, even when multiple resources are acquired within one statement.
Now, let us aggregate some objects:
class Logger
{
FileHandle original, duplex; // this logger can write to two files at once!
public:
Logger(const char* filename1, const char* filename2)
: original(filename1), duplex(filename2)
{
if (!filewrite_duplex(original, duplex, "New Session"))
throw "Ugh damn!";
}
}
The constructor of Logger will fail if original's constructor fails (because filename1 could not be opened), duplex's constructor fails (because filename2 could not be opened), or writing to the files inside Logger's constructor body fails. In any of these cases, Logger's destructor will not be called - so we cannot rely on Logger's destructor to release the files. But if original was constructed, its destructor will be called during cleanup of the Logger constructor.
RAII simplifies cleanup after partial construction.
Negative points:
Negative points? All problems can be solved with RAII and smart pointers ;-)
RAII is sometimes unwieldy when you need delayed acquisition, pushing aggregated objects onto the heap.
Imagine the Logger needs a SetTargetFile(const char* target). In that case, the handle, that still needs to be a member of Logger, needs to reside on the heap (e.g. in a smart pointer, to trigger the handle's destruction appropriately.)
I have never wished for garbage collection really. When I do C# I sometimes feel a moment of bliss that I just do not need to care, but much more I miss all the cool toys that can be created through deterministic destruction. (using IDisposable just does not cut it.)
I have had one particularly complex structure that might have benefited from GC, where "simple" smart pointers would cause circular references over multiple classes. We muddled through by carefully balancing strong and weak pointers, but anytime we want to change something, we have to study a big relationship chart. GC might have been better, but some of the components held resources that should be release ASAP.
A note on the FileHandle sample: It was not intended to be complete, just a sample - but turned out incorrect. Thanks Johannes Schaub for pointing out and FredOverflow for turning it into a correct C++0x solution. Over time, I've settled with the approach documented here.
There are excellent answers out there, so I just add some things forgotten.
##0. RAII is about scopes
RAII is about both:
acquiring a resource (no matter what resource) in the constructor, and un-acquiring it in the destructor.
having the constructor executed when the variable is declared, and the destructor automatically executed when the variable goes out of scope.
Others already answered about that, so I won't elaborate.
##1. When coding in Java or C#, you already use RAII...
MONSIEUR JOURDAIN: What! When I say, "Nicole, bring me my slippers,
and give me my nightcap," that's prose?
PHILOSOPHY MASTER: Yes, Sir.
MONSIEUR JOURDAIN: For more than forty years I have been speaking prose without knowing anything about it, and I am much obliged to you for having taught me that.
— Molière: The Middle Class Gentleman, Act 2, Scene 4
As Monsieur Jourdain did with prose, C# and even Java people already use RAII, but in hidden ways. For example, the following Java code (which is written the same way in C# by replacing synchronized with lock):
void foo()
{
// etc.
synchronized(someObject)
{
// if something throws here, the lock on someObject will
// be unlocked
}
// etc.
}
... is already using RAII: The mutex acquisition is done in the keyword (synchronized or lock), and the un-acquisition will be done when exiting the scope.
It's so natural in its notation it requires almost no explanation even for people who never heard about RAII.
The advantage C++ has over Java and C# here is that anything can be made using RAII. For example, there are no direct build-in equivalent of synchronized nor lock in C++, but we can still have them.
In C++, it would be written:
void foo()
{
// etc.
{
Lock lock(someObject) ; // lock is an object of type Lock whose
// constructor acquires a mutex on
// someObject and whose destructor will
// un-acquire it
// if something throws here, the lock on someObject will
// be unlocked
}
// etc.
}
which can be easily written as it would be in Java/C# (using C++ macros):
#define LOCK(mm_mutex) \
if(Lock lock{mm_mutex}) {} \
else
void foo()
{
// etc.
LOCK(someObject)
{
// if something throws here, the lock on someObject will
// be unlocked
}
// etc.
}
##2. RAII have alternate uses
WHITE RABBIT: [singing] I'm late / I'm late / For a very important date. / No time to say "Hello." / Goodbye. / I'm late, I'm late, I'm late.
— Alice in Wonderland (Disney version, 1951)
You know when the constructor will be called (at the object declaration), and you know when its corresponding destructor will be called (at the exit of the scope), so you can write almost magical code with but a line. Welcome to the C++ wonderland (at least, from a C++ developer's viewpoint).
For example, you can write a counter object (I let that as an exercise) and use it just by declaring its variable, like the lock object above was used:
void foo()
{
double timeElapsed = 0 ;
{
Counter counter(timeElapsed) ;
// do something lengthy
}
// now, the timeElapsed variable contain the time elapsed
// from the Counter's declaration till the scope exit
}
which of course, can be written, again, the Java/C# way using a macro:
void foo()
{
double timeElapsed = 0 ;
COUNTER(timeElapsed)
{
// do something lengthy
}
// now, the timeElapsed variable contain the time elapsed
// from the Counter's declaration till the scope exit
}
##3. Why does C++ lack finally?
[SHOUTING] It's the final countdown!
— Europe: The Final Countdown (sorry, I was out of quotes, here... :-)
The finally clause is used in C#/Java to handle resource disposal in case of scope exit (either through a return or a thrown exception).
Astute specification readers will have noticed C++ has no finally clause. And this is not an error, because C++ does not need it, as RAII already handle resource disposal. (And believe me, writing a C++ destructor is magnitudes easier than writing the right Java finally clause, or even a C#'s correct Dispose method).
Still, sometimes, a finally clause would be cool. Can we do it in C++? Yes, we can! And again with an alternate use of RAII.
##Conclusion: RAII is a more than philosophy in C++: It's C++
RAII? THIS IS C++!!!
— C++ developer's outraged comment, shamelessly copied by an obscure Sparta king and his 300 friends
When you reach some level of experience in C++, you start thinking in terms of RAII, in terms of construtors and destructors automated execution.
You start thinking in terms of scopes, and the { and } characters become ones of the most important in your code.
And almost everything fits right in terms of RAII: exception safety, mutexes, database connections, database requests, server connection, clocks, OS handles, etc., and last, but not least, memory.
The database part is not negligible, as, if you accept to pay the price, you can even write in a "transactional programming" style, executing lines and lines of code until deciding, in the end, if you want to commit all the changes, or, if not possible, having all the changes reverted back (as long as each line satisfy at least the Strong Exception Guarantee). (see the second part of this Herb's Sutter article for the transactional programming).
And like a puzzle, everything fits.
RAII is so much part of C++, C++ could not be C++ without it.
This explains why experienced C++ developers are so enamored with RAII, and why RAII is the first thing they search when trying another language.
And it explains why the Garbage Collector, while a magnificient piece of technology in itself, is not so impressive from a C++ developer's viewpoint:
RAII already handles most of the cases handled by a GC
A GC deals better than RAII with circular references on pure managed objects (mitigated by smart uses of weak pointers)
Still A GC is limited to memory, while RAII can handle any kind of resource.
As described above, RAII can do much, much more...
RAII is using C++ destructors semantics to manage resources. For example, consider a smart pointer. You have a parameterized constructor of the pointer that initializes this pointer with the adress of object. You allocate a pointer on stack:
SmartPointer pointer( new ObjectClass() );
When the smart pointer goes out of scope the destructor of the pointer class deletes the connected object. The pointer is stack-allocated and the object - heap-allocated.
There are certain cases when RAII doesn't help. For example, if you use reference-counting smart pointers (like boost::shared_ptr) and create a graph-like structure with a cycle you risk facing a memory leak because the objects in a cycle will prevent each other from being released. Garbage collection would help against this.
I'd like to put it a bit more strongly then previous responses.
RAII, Resource Acquisition Is Initialization means that all acquired resources should be acquired in the context of the initialization of an object. This forbids "naked" resource acquisition. The rationale is that cleanup in C++ works on object basis, not function-call basis. Hence, all cleanup should be done by objects, not function calls. In this sense C++ is more-object oriented then e.g. Java. Java cleanup is based on function calls in finally clauses.
I concur with cpitis. But would like to add that the resources can be anything not just memory. The resource could be a file, a critical section, a thread or a database connection.
It is called Resource Acquisition Is Initialization because the resource is acquired when the object controlling the resource is constructed, If the constructor failed (ie due to an exception) the resource is not acquired. Then once the object goes out of scope the resource is released. c++ guarantees that all objects on the stack that have been successfully constructed will be destructed (this includes constructors of base classes and members even if the super class constructor fails).
The rational behind RAII is to make resource acquisition exception safe. That all resources acquired are properly released no matter where an exception occurs. However this does rely on the quality of the class that acquires the resource (this must be exception safe and this is hard).
The problem with garbage collection is that you lose the deterministic destruction that's crucial to RAII. Once a variable goes out of scope, it's up to the garbage collector when the object will be reclaimed. The resource that's held by the object will continue to be held until the destructor gets called.
RAII comes from Resource Allocation Is Initialization. Basically, it means that when a constructor finishes the execution, the constructed object is fully initialized and ready to use. It also implies that the destructor will release any resources (e.g. memory, OS resources) owned by the object.
Compared with garbage collected languages/technologies (e.g. Java, .NET), C++ allows full control of the life of an object. For a stack allocated object, you'll know when the destructor of the object will be called (when the execution goes out of the scope), thing that is not really controlled in case of garbage collection. Even using smart pointers in C++ (e.g. boost::shared_ptr), you'll know that when there is no reference to the pointed object, the destructor of that object will be called.
And how can you make something on the stack that will cause the cleanup of something that lives on the heap?
class int_buffer
{
size_t m_size;
int * m_buf;
public:
int_buffer( size_t size )
: m_size( size ), m_buf( 0 )
{
if( m_size > 0 )
m_buf = new int[m_size]; // will throw on failure by default
}
~int_buffer()
{
delete[] m_buf;
}
/* ...rest of class implementation...*/
};
void foo()
{
int_buffer ib(20); // creates a buffer of 20 bytes
std::cout << ib.size() << std::endl;
} // here the destructor is called automatically even if an exception is thrown and the memory ib held is freed.
When an instance of int_buffer comes into existence it must have a size, and it will allocate the necessary memory. When it goes out of scope, it's destructor is called. This is very useful for things like synchronization objects. Consider
class mutex
{
// ...
take();
release();
class mutex::sentry
{
mutex & mm;
public:
sentry( mutex & m ) : mm(m)
{
mm.take();
}
~sentry()
{
mm.release();
}
}; // mutex::sentry;
};
mutex m;
int getSomeValue()
{
mutex::sentry ms( m ); // blocks here until the mutex is taken
return 0;
} // the mutex is released in the destructor call here.
Also, are there cases where you can't use RAII?
No, not really.
Do you ever find yourself wishing for garbage collection? At least a garbage collector you could use for some objects while letting others be managed?
Never. Garbage collection only solves a very small subset of dynamic resource management.
There are already a lot of good answers here, but I'd just like to add:
A simple explanation of RAII is that, in C++, an object allocated on the stack is destroyed whenever it goes out of scope. That means, an objects destructor will be called and can do all necessary cleanup.
That means, if an object is created without "new", no "delete" is required. And this is also the idea behind "smart pointers" - they reside on the stack, and essentially wraps a heap based object.
RAII is an acronym for Resource Acquisition Is Initialization.
This technique is very much unique to C++ because of their support for both Constructors & Destructors & almost automatically the constructors that are matching that arguments being passed in or the worst case the default constructor is called & destructors if explicity provided is called otherwise the default one that is added by the C++ compiler is called if you didn't write an destructor explicitly for a C++ class. This happens only for C++ objects that are auto-managed - meaning that are not using the free store (memory allocated/deallocated using new,new[]/delete,delete[] C++ operators).
RAII technique makes use of this auto-managed object feature to handle the objects that are created on the heap/free-store by explcitly asking for more memory using new/new[], which should be explicitly destroyed by calling delete/delete[]. The auto-managed object's class will wrap this another object that is created on the heap/free-store memory. Hence when auto-managed object's constructor is run, the wrapped object is created on the heap/free-store memory & when the auto-managed object's handle goes out of scope, destructor of that auto-managed object is called automatically in which the wrapped object is destroyed using delete. With OOP concepts, if you wrap such objects inside another class in private scope, you wouldn't have access to the wrapped classes members & methods & this is the reason why smart pointers (aka handle classes) are designed for. These smart pointers expose the wrapped object as typed object to external world & there by allowing to invoke any members/methods that the exposed memory object is made up of. Note that smart pointers have various flavors based on different needs. You should refer to Modern C++ programming by Andrei Alexandrescu or boost library's (www.boostorg) shared_ptr.hpp implementation/documentation to learn more about it. Hope this helps you to understand RAII.