John
John

Reputation: 1915

try finally how to free memory

I am new to C++ in VS C++. I'm creating win32 dll library. I have a major basic problem with try finally block.

Let's pretend I have something like this:

class object {
  private:
    int* foo;
  public:
    object() : foo(new int()) { *foo = 42; }
    ~object() { 
      // Now since foo is dynamically allocated, the destructor
      // needs to deallocate it
      delete foo;
    }
};

int main() {
  vector<object*> tmp;
  tmp.push_back(new object());

  // Do some stuff with tmp

  for (int i = 0; i < tmp.size(); ++i) {
    delete tmp[i]; // Calls ~object (which deallocates tmp[i]->foo) 
                   // and deallocates *tmp[i]
  }
  tmp.clear();

  return 0;
}

I have copied the code snippet from: Another stackoverflow question

In the above example, how can I use the "free" part so that it could be always freed up as the method finishes its job? I thought try finally should suffice.

But now I can see that there are several: try, __try Don't know what is the difference. With __try I get compiler errors which says something about RAII ...

Could anyone help me with this?

Upvotes: 1

Views: 179

Answers (2)

Peter
Peter

Reputation: 36637

There are various ways.

One is to make the vector<object *> a vector<unique_pointer<object> >. No need to explicitly deallocate the objects at all.

Another is to place the vector<object *> a member of another class that manages the deallocation. So, when an instance of that class is destroyed, its destructor releases all the elements of the vector in your code. You will need to supply other constructors and member functions for that class, to manage adding objects to the vector properly.

Upvotes: 1

Barry
Barry

Reputation: 304122

It's Resource Acquisition Is Initialization, RAII for short. The idea there being that if an object owns a resource, its destructor should free it automatically. In all of these cases, with C++11 you'd want to use std::unique_ptr instead of raw pointers. So, for instance:

class object {
    std::unique_ptr<int> foo; 

public:
    object() : foo(std::make_unique<int>(42)) { }
    // no destructor necessary here
};

int main() {
    std::vector<std::unique_ptr<object>> tmp;
    tmp.push_back(std::make_unique<object>());

    // when tmp goes out of scope, each object in it will already
    // be deleted for you, no code necessary
}

Of the many advantages here is the fact that now you don't have to worry about writing the copy constructor for object (as-is, your foo will get deleted twice if you copy it). See also Rule of Zero

Upvotes: 4

Related Questions