In brief, my question is about member variables as pointers in unmanaged C++.
In java or c#, we have "advanced pointer". In fact, we can't aware the "pointer" in them. We usually initialize the member of a class like this:
member = new Member();
or
member = null;
But in c++, it becomes more confusing. I have seen many styles: using new, or leave the member variable in stack.
In my point of view, using boost::shared_ptr seems friendly, but in boost itself source code there are news everywhere. It's the matter of efficiency,isn't it?
Is there a guildline like "try your best to avoid new" or something?
EDIT
I realize it's not proper to say "leave them in stack", here's a more proper way to say: when i need an object to be my member variable, should i prefer a object than a object*?
The Boost source code is not a good example for how you should write your source code. The Boost libraries are designed to wrap up all the tedious, difficult, and error-prone code so that you don't have to worry about it in your code.
Your best bet is to follow two general rules in your code:
Don't use pointers where you don't need to use pointers
Where you do need to use pointers, use smart pointers (like shared_ptr or scoped_ptr)
Yes, there is a guideline - only use dynamic allocation when you must. A lot of the time yo can and should be using values, not pointers. For example, you should almost always be using:
vector <string> v;
rather than:
vector <string *> v;
and allocating the strings dynamically.
Certainly it won't kill you if you do a single new in the constructor, and a single delete in the destructor. In a simple case like that, using smart pointers is just pointless overhead.
If you go more complicated, or if you are paranoid about exception safety, smart pointers may very well be a good idea.
The guide to the language by Stroustrup:
Scott Meyers's triple are quite useful: Effective C++, More Effective C++, and
Effective STL.
Also see these questions:
- https://stackoverflow.com/questions/155762/best-c-resource
- Java FAQ equivalent of C++ FAQ lite?
- C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4]
- What C++ pitfalls should I avoid?
- New to C++. Question about constant pointers
The benefit of using shared_ptr is that it is a "smart pointer" that does not require an explicit delete to free the memory. Otherwise, if you use new you will have to explicitly call delete to free the allocated memory once the object is no longer required.
In C++ it is a matter of choice to the developer. There is more power but also more responsibility that goes with it.
Example:
A class that declares an object with internal storage of arbitrary size.
If you design this class to allocate worst case storage at instantiation you can avoid pointers altogether. But the cost is heavy in terms of memory usage for the average case.
If you design the class to allocate memory based on its needs you might choose to use pointers. Then each instance will take only what it needs from the heap. But you must use care to avoid pointer bugs.
If you design the class to allocate memory based on its needs you might still be able to avoid pointers using abstractions for the memory (i.e. auto_ptr or a custom buffer scheme, etc.).
So a guideline might be to explore the options available before resorting to naked pointers in application code. The balance might be different for library code since it will be more limited in scope, possibly more performance sensitive, and (hopefully) better tested.
You may want to use the C++ STL class "autoptr" to take care of managing your memory.
Also, in C++, if it is a member variable, it doesn't have to be a pointer.
class MyClass
{
MyClass();
MyMember a;
MyMember* b;
std::auto_ptr<MyMember> c;
}
MyClass::MyClass()
{
// constructer
// a is now instantiated -- I don't have to do anything
b = new MyMember(); // I'll have to delete it in the destructor
c.reset(new MyMember()); // I won't have to delete it in the destructor
}
Related
I am new to smart pointers, I liked using them for the safety and power of sharing object...
I have one question: If my class manages a resource in its constructors and destructors applying some rules of thumb like the Big 5 and the Big 3... Should I still use smart pointers? or my class is an alternative to them. Because as I've read in C++ primer 5 edition that smart pointers came to solve problems raw pointers were facing like memory-leaks, double-deleting pointers and accessing a dangling pointer... My class can avoid those problems:
class BallGame {
public:
using Resource = int;
BallGame(int);
BallGame(const BallGame&);
BallGame(BallGame&&);
BallGame& operator=(const BallGame&);
BallGame& operator=(BallGame&&);
~BallGame();
private:
Resource m_res;
};
Consider that the member of my class are doing the right job so can I avoid smart pointer?
I want to know some scenarios when I should use smart pointers rather than managing resources in my class.
Are they really for "dumb classes" (classes that define constructors but not well-behaved destructors) like in C++ primer book.
Your question can be read as
If I implement correct semantics for memory ownership of a smart pointer by hand in each class I use, can I avoid using smart pointers?
Yes, but why? When you need a dynamic array do you reimplement basic std::vector semantics by hand every time you need it? I don't think so.
It's the purpose of libraries, avoiding reinventing the wheel every time.
Another benefit of smart pointers that has not been mentioned yet is that they give whoever is reading the code a decent idea of the lifetime of that object. The thing with a raw pointer is (especially as code gets more complicated) it can be difficult to figure out who is responsible for calling delete on the object whereas if you have a unique pointer instead we know immediately that the deletion will happen automatically when the pointer goes out of scope.
As you've read in your book: They solve the issues raw-pointers facing thus: consider this:
int* ptr = new int[1024];
// oh my God! forgot to free it then welcome to memory leak
std::string* pStr = new std::string("Hello");
delete pStr;
//...
// and at some point in the program you think it is time to free pStr which has been already freed (among hundreds of code lines) then welcome to U.B.
std::cout << *pStr << std::endl; // pStr is a dangling pointer. U.B
To solve this using smart pointers:
std::unique_ptr<int> upi = std::make_unique(7);
// use upi effectively and don't care about freeing it because it automatically will be freed for you.
Another reason your class cannot support is sharing the same object among many objects effectively. In fact you can achieve that through applying a shallow-copy in your class but the Problem is who will free that resource then you end up implementing the functionality of a shared_ptr in your maybe small class!
Each new version of C++ comes with new facilities and new powerful features so you should stick to these libraries instead re-inventing the well. If only for some educational reason then it is OK to practice.
If you look you'll find real programs contains smart pointers as members which make your class robust.
I am learning C++. I have C, C#, ObjC background. Pretty higher level languages.
On C# or ObjC , it's trivial returning heap allocated object as a result of a function or method. Because the cleanup of objects are managed (by convention). It will be destroyed at proper time.
But I don't know how should I handle this in C++.
For example,
std::string* makeString()
{
std::string* str = GetSomeStringFromArbitrarySource ();
SaveSomewhereElseInternally (str);
return str;
}
void useString ()
{
std::string* str = makeString ();
// Where and how should I cleanup the `str` object?
// It is not safe `delete str` here because it may be used on another place.
}
What is the recommended and conventional way to cleanup heap allocated object when it is passed over many functions?
I looked several smart pointers, but they don't look really reduce complexity or things to care. Am I misunderstanding the smart pointers?
I looked several smart pointers, but they don't look really reduce complexity or things to care. Am I misunderstanding the smart pointers?
Most likely, yes. In C++, since you have to handle this yourself (no GC will clean it up for you), you need a way to track the usage of each and every object.
You can manually match every new with a delete, but this is sometimes difficult or impossible, such as in your scenario above. There is no way to know whether the object is being used elsewhere.
Smart pointers solve this by managing the lifetime for you, so you don't need to delete. They use various mechanisms to track how many places the object is being used, and call delete when the last one is done.
That being said, there isn't much reason in this specific case to use pointers at all. If you're working with std::string, you can pass the string around by value and it will never be an issue.
You are misunderstanding the smart pointers most probably by the same reason why you wrote:
std::string* makeString()
Instead of what most C++ programmers would write instead:
std::string makeString()
You would need to better understand object lifetime in C++ and then smart pointers concept would be much easier.
You need to figure out the desired lifetime for your objects, and then use the type system to enforce that lifetime.
From your example, it isn't at all clear when you want the object to be destroyed.
In C++, it is common for objects to be passed around by value (as primitive types are in Java/C#/etc), so unless you have some need to share the std::string between different pieces of code, the usual thing would be to just return the string by value (write makeString as std::string makeString()).
If you do need to have multiple places referencing the same object, you should think carefully about the design, and decide what single part of the program can safely control the lifetime of the object. Create the object by value in that place, and then pass pointers and references elsewhere.
Possibly you are misunderstanding smart pointers. In C++ the alternative is that the programmer needs to track the lifetime and usage of dynamically allocated objects. This affects the design of the software and also leads to human errors creeping in. When you use smart pointers , the lifetime of an object is pretty much taken care of for you.
I was brought up with the classical style of C++ (no smart pointers) and so I'm able to program that way , if required, but if you're starting out with c++ then smart pointers really is a must.
If you can use C++11 use shared pointers. These pointers implement a mechanism to delete the allocated object once the last of them is destroyed. If you are using C++03, use boost's shared pointers. If you can not use either, try to wrap heap allocations in classes you allocate on the stack, then pass references to those around, also give the RAII wiki a read.
The more I read about RAII, I understand that using the stack is the way to make sure that the code is exception safe.
Does that mean every time I am doing a new() in my code, I am doing something wrong in the sense there is a better way to do it using the RAII principle?
You're not necessarily doing something wrong if you use new, but it's worth checking that you're doing it right.
The result of the new expression should be immediately placed under the control of a smart pointer, usually by passing it straight into the constructor.
If that smart pointer is a shared_ptr, then you are probably doing it wrong. You should probably use make_shared instead. There are some situations where you shouldn't (use of weak_ptr to large objects), and some where you can't (C++03 without Boost).
If you use delete then you pretty much are doing it wrong, unless you are writing your own smart pointer class. And even then, your smart pointer might be able to use another smart pointer to save work.
This is not essential, but if you use new solely because the object is "too big for the stack", consider writing a class that acts as a handle to the object, using unique_ptr or scoped_ptr to manage it, so that from the user's point of view the objects they deal with are automatic variables. If you feel like it, you can extend this to the full PImpl idiom. Even if you don't want another class, consider a function that creates the object and returns a unique_ptr to it, which you can then call like auto foohandle = give_me_a_foo();. Then give_me_a_foo contains new, but other user code doesn't, and you encourage the practice of automatically stuffing things into RAII objects.
There are alternative resource-management strategies to RAII in C++, but you'd know about it if you were using them, and that would affect what counts as "wrong".
I think you have not fully grasp what RAII really means. Dynamic allocations, in the same way that other resources like files, connections to databases, etc. are needed in programs. RAII focuses on how to manage those resources, and the way to go is to have the resources managed by objects with automatic storage duration (either stack, or as a member of another object).
That does not mean that every resource must be allocated in the stack, but rather that if you allocate something in the heap, you should delegate the responsibility of managing that memory to an object that is in the stack.
Not at all. If the nature of the beast (the allocation requirements) is truly dynamic, eventually it is either going to come from a heap or some severe trickery on the stack pointer.
The best you can do is to use wrappings that scope-guard for you. (I can' tell you how often I use std::vector<> when i need a dynamic temp buffer that is scope protected). It is one of the most ideal reasons to use well maintained and designed libraries like STL, etc. And unlike C# or Java, its predictable, which has tremendous value when truly needed.
No, stack space is very limited so you don't want to put huge things on it, hence the term stack overflow. Also if you need an object to have a lifetime longer than your function, then you can't put it on the stack.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
In C++, why should new be used as little as possible?
Is it really a bad idea to use 'new' in instantiating a class in C++? Found here.
I get that using raw pointers is ill-advised, but why have a 'new' keyword at all when it's such bad practice? Or is it?
The point is that new, much like a pregnancy, creates a resource that is managed manually (i.e. by you), and as such it comes with responsibility.
C++ is a language for library writing, and any time you see a responsibility, the "C++" approach is to write a library element that handles this, and only this, responsibility. For dynamic memory allocation, those library components already exist and are summarily referred to as "smart pointers"; you'll want to look at std::unique_ptr and std::shared_ptr (or their TR1 or Boost equivalents).
While writing those single-responsibility building blocks, you will indeed need to say new and delete. But you do that once, and you think about it carefully and make sure you provide the correct copy, assignment and destruction semantics. (From the point of exception safety, single responsibility is crucial, since dealing with more than one single resource at a time is horribly unscalable.)
Once you have everything factored into suitable building blocks, you compose those blocks into bigger and bigger systems of code, but at that point you don't need to exercise any manual responsibility any more, since the building blocks already do this for you.
Since the standard library offers resource managing classes for the vast majority of use cases (dynamic arrays, smart pointers, file handles, strings), the point is that a well-factored and crafted C++ project should have very little need for any sort of manual resource management, which includes the use of new. All your handler objects are either automatic (scoped), or members of other classes whose instances are in turn scoped or managed by someone.
With this in mind, the only time you should be saying new is when you create a new resource-managing object; although even then that's not always necessary:
std::unique_ptr<Foo> p1(new Foo(1, 'a', -2.5)); // unique pointer
std::shared_ptr<Foo> p2(new Foo(1, 'a', -2.5)); // shared pointer
auto p3 = std::make_shared<Foo>(1, 'a', -2.5); // equivalent to p2, but better
Update: I think I may have addressed only half the OP's concerns. Many people coming from other languages seem to be under the impression that any object must be instantiated with a new-type expression. This is in itself a very unhelpful mindset when approaching C++:
The crucial distinction in C++ is that of object lifetime, or "storage class". This can be one of: automatic (scoped), static (permanent), or dynamic (manual). Global variables have static lifetime. The vast majority of all variables (which are declared as Foo x; inside a local scope) have automatic lifetime. It is only for dynamic storage that we use a new expression. The most important thing to realize when coming to C++ from another OO language is that most objects only ever need to have automatic lifetime, and thus there is never anything to worry about.
So the first realization should be that "C++ rarely needs dynamic storage". I feel that this may have been part of the OP's question. The question may have been better phrased as "is it a really bad idea to allocate objects dynamically?". It is only after you decide that you really need dynamic storage that we get to the discussion proper of whether you should be saying new and delete a lot, or if there are preferable alternatives, which is the point of my original answer.
Avoiding new as much as possible, means many benefits, such as:
First and foremost, you also avoid delete statements.Though smart pointers can help you here. So this is not that strong point.
You avoid Rule of Three (in C++03), or Rule of Five (in C++11). If you use new when designing a class, that is, when your class manages raw memory internally, you probably have to consider this rule.
It's easy to implement exception-safe code when you don't use new. Otherwise, you've to face hell lot of problems, making your code exception-safe.
Using new unnecessarily means you're inviting problems. I've seen when an inexperienced programmer uses new, he has often better alternatives, such as usage standard containers, and algorithms. Use of standard containers avoids most problems which comes with explicit use of new.
It's not bad, but everything you allocate with new, has to be deallocated with a delete. This is not always trivial to do, especially when you take into account exceptions.
I think that is what that post meant.
It's not a "bad idea to use new" -- the poster misstated his case rather badly. Rather, using new and not give you two different things.
new gives you a new, separately allocated instance of the class, and returns a pointer to that instance.
Using the class name without new creates an automatic instance of the class that will go "poof" when it passes out of scope. This "returns" the instance itself, not a pointer (and hence the syntax error in that other thread).
If you use new in the referenced case and added * to pass the compiler, it would result in a leaked object. If, on the other hand, you were passing a parameter to a method that was going to store it somewhere, and you passed a non-newed instance, making it work with &, you'd end up with a dangling pointer stored.
new what you delete, and free what you malloc (don't mix them, you'll get into trouble). Sometimes you have to use new, as data allocated with new will not fall out of scope... unless the data pointer is lost, which is the entire issue with new.
But that is err on the side of the programmer, not the keyword.
It depends on what the code needs. It the reply you refer to, the vector contains client instances, not pointers to client instances.
In C++, you can create object directly on the stack, without using new, like V1 and V2 in the code below:
void someFct()
{
std::vector<client> V1;
//....
std::vector<client*> V2;
}
When using V2, you will have to create new client instance with the new operation, but the client objects will not be released (deleted) when V2 will go out of scope. There is no garbage collector. You have to delete the objects before leaving the function.
To have the created instances deleted automatically, you can use std::shared_ptr. That make the code a bit longer to write, but it is simpler to maintain in the long term:
void someFct()
{
typedef std::shared_ptr<client> client_ptr;
typedef std::vector<client_ptr> client_array;
client_array V2;
V2.push_back(client_ptr(new client()));
// The client instance are now automatically released when the function ends,
// even if an exception is thrown.
}
Is it really a bad idea to use 'new' in instantiating a class in C++?
It’s often bad because it’s not necessary, and code gets much easier when you’re not using it spuriously. In cases where you can get away without using it, do so. I’ve written whole libraries without once using new.
I get that using raw pointers is ill-advised, but why have a 'new' keyword at all when it's such bad practice? Or is it?
It’s not universally bad, just unnecessary most of the time. But there are also times when it’s appropriate and that’s why there is such a keyword. That said, C++ could have gotten away without the keyword, since new conflates two concepts: 1. it allocates memory, and 2. it initialises the memory to an object.
You can decouple these processes by using other means of memory allocation, followed by a constructor invocation (“placement new”). This is actually done all over the place, such as the standard library, via allocators.
On the other hand, it’s rarely (read: never) meaningful for client code to manage uninitialised memory so it makes sense not to decouple these two processes. Hence the existence of new.
I am pretty proficient with C, and freeing memory in C is a must.
However, I'm starting my first C++ project, and I've heard some things about how you don't need to free memory, by using shared pointers and other things.
Where should I read about this? Is this a valuable replacement for proper delete C++ functionality? How does it work?
EDIT
I'm confused, some people are saying that I should allocate using new and use smart pointers for the deallocation process.
Other people are saying that I shouldn't allocate dynamic memory in the first place.
Others are saying that if I use new I also have to use delete just like C.
So which method is considered more standard and more-often used?
Where should I read about this?
Herb Sutter's Exceptional C++ and Scott Meyers's More Effective C++ are both excellent books that cover the subject in detail.
There is also a lot of discussion on the web (Google or StackOverflow searches for "RAII" or "smart pointer" will no doubt yield many good results).
Is this a valuable replacement for proper delete C++ functionality?
Absolutely. The ability not to worry about cleaning up resources, especially when an exception is thrown, is one of the most valuable aspects of using RAII and smart pointers.
What I meant in my comment (sorry for being terse - I had to run out to the shops) is that you should be using:
std::string s = "foobar";
rather than:
std::string * s = new std::string( "foobar" );
...
delete s;
and:
vector <Person> p;
p.push_back( Person( "fred" ) );
rather than:
vector <Person *> p;
p.push_back( new Person( "fred" ) );
You should always be using classes that manage memory for you. In C++ the main reason for creating an object using new is that you don't know its type at compile-time. If that isn't the reason, think long and hard before using new and delete, or even smart pointers.
If you allocate dynamic memory (with new), you need to free it (with delete), just like using malloc/free in C. The power of C++ is that it gives you lots of ways of NOT calling new, in which case you don't need to call delete.
You still have to worry about freeing memory in C++, it's just that there are better methods/tools for doing so. One can argue that attention to memory management in C++ is more difficult as well due to the added requirement of writing exception safe code. This makes things such as:
MyClass *y = new MyClass;
doSomething(y);
delete y;
Look completely harmless until you find that doSomething() throws an exception and now you have a memory leak. This becomes even more dangerous as code is maintained as the code above could have been safe prior to someone changing the doSomething() function in a later release.
Following the RAII methodology is a big part of fixing memory management challenges and using auto_ptr's or shared pointers provided by libraries such as Boost make it easier to incorporate these methods into your code.
Note that auto_ptr is not a "shared" pointer. It is an object that takes ownership of the dynamically allocated object and gives that ownership away on assignment and copy. It doesn't count references to the memory. This makes it unsuitable for use within standard containers and many in general prefer the shared_ptr of Boost to the auto_ptr provided by the standard.
It is never safe to put auto_ptrs into
standard containers. Some people will
tell you that their compiler and
library compiles this fine, and others
will tell you that they've seen
exactly this example recommended in
the documentation of a certain popular
compiler; don't listen to them.
The problem is that auto_ptr does not
quite meet the requirements of a type
you can put into containers, because
copies of auto_ptrs are not
equivalent. For one thing, there's
nothing that says a vector can't just
decide to up and make an "extra"
internal copy of some object it
contains. For another, when you call
generic functions that will copy
elements, like sort() does, the
functions have to be able to assume
that copies are going to be
equivalent. At least one popular sort
internally takes a copy of a "pivot"
element, and if you try to make it
work on auto_ptrs it will merrily take
a copy of the pivot auto_ptr object
(thereby taking ownership and putting
it in a temporary auto_ptr on the
side), do the rest of its work on the
sequence (including taking further
copies of the now-non-owning auto_ptr
that was picked as a pivot value), and
when the sort is over the pivot is
destroyed and you have a problem: At
least one auto_ptr in the sequence
(the one that was the pivot value) no
longer owns the pointer it once held,
and in fact the pointer it held has
already been deleted!
Taken From: Using auto_ptr Effectively
Well, of course you need to delete. I would rephrase this as 'what libraries can I use that can automate the deletion of allocated memory?'. I'd recommend you start by reading up the Boost Smart pointers page.
The best answer I can give you is: something needs to call delete for each object created with new. Whether you do it manually, or using a scope-based smart pointer, or a reference-counted smart pointer, or even a non-deterministic garbage collector, it still needs to be done.
Having said that, I have not manually called delete in 10 years or so. Whenever I can I create an automatic object (on the stack); when I need to create an object on the heap for some reason I try using a scope-based smart pointer, and in rare cases when there is a legitimate reason to have shared ownership, I use a reference counted smart pointer.
This is a great question, and actually several in one:
Do I need to worry about Managing Memory?
Yes! There is no garbage collection in C++. Anytime you allocate something with new you need to either call delete in your own code, or delegate that responsibility to something like a smart pointer.
When Should I use dynamic memory allocation?
The reasons you'd want to use dynamic memory allocation (allocating with new). Some of these include:
You don't know the size of the thing you are allocating at compile time
You don't know the type of the thing you are allocating at compile time
You are reusing the same data in different contexts and don't want to pay the performance overhead of copying that data around.
There are lots of other reasons, and these are gross over generalizations, but you get the idea.
What tools can I use to help me with memory management?
Smart pointers are the way to go here. A smart pointer will take ownership of memory that you allocate, and then release that memory automatically for you at a specific time depending on the policy the smart pointer.
For example, a boost::scoped_ptr will deallocate memory for you when it goes out of scope
{
scoped_ptr<MyClass> myVar( new MyClass() );
// do Something with myVar
} // myVar goes out of scope and calls delete on its MyClass
In general you should use smart pointers over raw pointers anytime you can. It will save you years of tracking down memory leaks.
Smart pointers come in many forms including:
std::auto_ptr
Boost Smart Pointers
If you can use Boost smart pointers I would. They rock!
Since C++ does not have a garbage collector built into the language, you need to be aware of what memory you have dynamically allocated and how that memory is being freed.
That said, you can use smart pointers to alleviate the problem of having to manually free memory via delete - for example, see Smart Ponters (boost).
First and foremost, before you get into the business of using auto_ptr's and writing your own RAII classes, learn to use the Standard Template Library. It provides many common container classes that automatically allocate their internal memory when you instantiate them and free it up when they go out of scope - things like vectors, lists, maps, and so forth. When you employ STL, using the new-operator and delete (or malloc and free) is rarely necessary.
Freeing memory in C++ is just as much a must as in C.
What you may be thinking of is a smart pointer library (the standard library's auto_ptr among others) - which will do reference counting for you.
'm confused, some people are saying
that I should allocate using new and
use smart pointers for the
deallocation process.
They're right. Just like in C you still need to manage all your memory one way or another. however there are ways to use the language to automate delete.
Smart pointers are basically local scope wrappers for pointers which use the object .dtor to delete the corresponding pointer once the smart pointer - which is like any other objecton the stack - goes out of scope
The beauty of C++ is that you have explicit control over when things are created and when things are destroyed. Do it right and you will not have issues with memory leaks etc.
Depending on your environment, you may want to create objects on the stack or you may want to dynamically allocated (create them on the 'heap' - heap in quotes because its an overused term but is good enough for now).
Foo x; // created on the stack - automatically destroyed when the program exits that block of code it was created in.
Foo *y = new Foo; // created on the heap - its O.K. to pass this one around since you control when its destroyed
Whenever you use 'new', you should use the corresponding version of delete... somewhere, somehow. If you use new to initialize a smart pointer like:
std::auto_ptr x = new Foo;
You are actually creating two items. An instance of auto_ptr and an instance of Foo. auto_ptr is created on the stack, Foo on the heap.
When the stack 'unwinds', it will automatically call delete on that instance of Foo. Automatically cleaning it up for you.
So, general rule of thumb, use the stack version whenever possible/practical. In most instances it will be faster as well.
In order of preference, you should:
Avoid handling allocation yourself at all. C++'s STL (standard template library) comes with a lot of containers that handle allocation for you. Use vector instead of dynamically allocated arrays. Use string instead of char * for arrays of characters. Try to seek out an appropriate container from the STL rather than designing your own.
If you are designing your own class and honestly need dynamic allocation (and you usually won't if you compose your class using members of the STL), place all instances of new (new[]) in your constructor and all instances of delete (delete[]) in your destructor. You shouldn't need malloc and free, generally.
If you are unable to keep your allocations paired within constructors and destructors, use smart pointers. Really this is not so different from #2; smart pointers are basically just special classes which use destructors to ensure deallocation happens.