Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the usage of new and delete, and Stroustrup's advice

Tags:

c++

c++11

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 using new and delete, 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.

like image 642
user3111311 Avatar asked Dec 30 '13 22:12

user3111311


People also ask

How does new and delete work?

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.

What actually happens when you use Delete on something allocated with new []?

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.

Do you have to use delete with new?

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.

What is ownership in C++?

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.

When to use'new'and'delete'when creating an object?

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.

What is the difference between the new and delete operator?

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.

When to use intrusive lists in C++?

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.

When to throw an exception from a destructor?

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.


2 Answers

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.

like image 80
Joseph Mansfield Avatar answered Sep 20 '22 21:09

Joseph Mansfield


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.

like image 23
Dietmar Kühl Avatar answered Sep 22 '22 21:09

Dietmar Kühl