About the usage of new and delete, and Stroustrup's advice...
He says something like (but not exactly, this is from my notes of his book):
A rule of thumb is that,
new
belongs in constructors and similar operations,delete
belongs in destructors. In addition,new
is often used in arguments to resource handles. Otherwise avoid usingnew
anddelete
, use resource handles (smart pointers) instead.
I was wondering if the more experienced folks with C++11 have really applied this or not.
My impression of this was, wow this seems like a really cool rule to follow. But then I got suspicious, as for any general rule. At the end of the day you will end up using new and delete wherever necessary. But maybe this rule is a good guideline I don't know.
The deallocation counterpart of new is delete, which first calls the destructor (if any) on its argument and then returns the memory allocated by new back to the free store. Every call to new must be matched by a call to delete; failure to do so causes memory leaks.
The code calls operator new[] to allocate memory for 10 string object, then call the default string constructor for each array element. In the way, when the delete operator is used on an array, it calls a destructor for each array element and then calls operator delete[] to deallocate the memory.
There is nothing that requires a delete[] in the standard - However, I would say it is a very good guideline to follow. However, it is better practice to use a delete or delete[] with every new or new[] operation, even if the memory will be cleaned up by the program termination.
An owner is an object containing a pointer to an object allocated by new for which a delete is required. Every object on the free store (heap, dynamic store) must have exactly one owner. If there are two pointers to an object on the free store, only one can be the owner.
Basically, you should only use "new" if you want an object to live beyond the lifetime of the scope you create it in. That done, you need to use "delete" to destroy it.
The new operator requests for the memory allocation in heap. If the sufficient memory is available, it initializes the memory to the pointer variable and returns its address. The delete operator is used to deallocate the memory.
Use a hand-crafted intrusive lists only where a list and the last ounce of performance is needed. People sometimes worry about the cost of std::vector growing incrementally.
From a destructor? Yes: You should throw an exception from a constructor whenever you cannot properly initialize (construct) an object. There is no really satisfactory alternative to exiting a constructor by a throw.
It's a great rule. In fact, you can avoid using new
in arguments to smart pointers by using the appropriate make_
functions. For example, instead of:
std::shared_ptr<int> p(new int(5));
You can often do:
auto p = std::make_shared<int>(5);
This also has the benefit of being more exception safe. While a std::make_unique
doesn't yet exist, it is planned to make its way into C++14 (it is already in the working draft). If you want it now, there are some existing implementations.
You can go a step further and even avoid using new
and delete
in constructors and destructors. If you always wrap dynamically allocated objects in smart pointers, even when they're class members, you won't need to manage your own memory at all. See the Rule of Zero. The idea is that it's not the responsibility of your class to implement any form of ownership semantics (SRP) - that's what the smart pointers are for. Then you theoretically never have to write copy/move constructors, copy/move assignment operators or destructors, because the implicitly defined functions will generally do the appropriate thing.
Seems more like a poll than a question but here it goes: in application code I generally don't use new
at all. Due to our coding guidelines the code does use pointer but none of these "naked" pointers is actually transfering ownership. All objects are owned by some other object.
To be fair, when objects need to be allocated the allocation generally uses something morally equivalent to std::make_shared<T>(...)
which sometimes does show up in application code. One major reason for this rather thorough absence of new
(or similar) is that objects are generally allocated using stateful allocators and not doing so via a resource manager actually happens to be fairly complicated. Thus, there is little place for direct memory allocation using new
or a placement version thereof in application code.
In some infrastructure code, especially when creating custom containers the situation is slightly different: there is memory allocated (from allocators and initialized using placement new
) there. However, even there any result from memory allocation and initialization of objects is immediately passed on to resource managers. Basically, I can't cope with explicit resource management and using resource managers just reliefs me of the necessary work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With