3

I have a structure

typedef struct myStruct_st
{
  int a;
}myStruct;

It can be created using

myStruct * myStruct_new()
{
  printf("Allocate\n");
  return new myStruct;
}

And deleted using

static void myStruct_free(myStruct * ptr)
{
  printf("Deallocate\n");
  delete ptr;
}

I want the memory allocated for the structure freed automatically

To this end, I wrote a template

template <class T>
class scoped_del
{
 public:
  scoped_del(T * p, void (*mfree)(T *)) :
   p_(p),
   mfree_(mfree)
  {
  }

  ~scoped_del()
  {
   mfree_(p_);
  }

 private:

  T * p_;

  void (*mfree_)(T *);
};

And use it like that

int main()
{
  myStruct * st = myStruct_new();

  class scoped_del<myStruct> ptr_st(st, myStruct_free);

  return 0;
}

How can I make it a more standard way using stl or boost?

Stals
  • 1,543
  • 4
  • 27
  • 52
Max
  • 65
  • 5

2 Answers2

3

Boost's shared_ptr does pretty much the same thing, in pretty much the same code.

#include <boost/shared_ptr.hpp>

main() {
    boost::sshared_ptr<myStruct> ptr_st(myStruct_new(), myStruct_free);

    ptr_st->a = 11;
}

But you should consider whether you want to be writing C++ code or C code. You're using some very C-style syntax (typdef struct, class in front of declarations, using a "new function" instead of a constructor, using a "free function" instead of a destructor), but you tagged this C++ and clearly you are using some C++ features. If you want to use C++, use all of it's features, and if you don't want to do that then stick with C. Mixing the two too much is going to cause a lot of confusion for anyone trying to figure out your code (and your "design decisions").

SoapBox
  • 20,457
  • 3
  • 51
  • 87
  • I am using openssl library in c++ code and just wanted to find an easy way to autodelete openssl's structures without wrapping it into classes. – Max Jul 16 '10 at 10:59
  • 1
    seems that there is no constructor for boost::scoped_ptr wich takes new/delete function pointers: test1.cpp:23: error: no matching function for call to ‘boost::scoped_ptr::scoped_ptr(myStruct* (&)(), void (&)(myStruct*))’ – Max Jul 16 '10 at 11:08
  • 1
    ok, it all right, but with shared_ptr instead of scoped_ptr: boost::shared_ptr ptr_st(myStruct_new(), myStruct_free); – Max Jul 16 '10 at 11:28
  • `boost::scoped_ptr` cannot use deleter. – big-z Jul 16 '10 at 12:20
1

I know this is an old post but I just found it and I figure others probably will also. I'm also looking for an auto_ptr style smart pointer but which takes a deleter object and for the same reason as the OP, I'm also using the openssl library and want to wrap the resource. I am using boost::shared_ptrs with deleters() for managing openssl objects but I found out the hard way that you have to be careful because some of the openssl calls take ownership of the pointers you pass them. This can cause a problem if you are storing it in a shared_ptr because you then end up with a double-delete scenario. Also, semantically I don't actually want to "share" ownership of this objects with anyone. My usage has been either "I own it" or "I want to give it to someone else".

The new C++0x unique_ptr<> may offer a solution but in the mean time use shared_ptr carefully with openssl objects, it could bite you.

Richard
  • 228
  • 1
  • 2
  • 10