Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
230 views
in Technique[技术] by (71.8m points)

c++11 - Are there any valid use cases to use new and delete, raw pointers or c-style arrays with modern C++?

Here's a notable video (Stop teaching C) about that paradigm change to take in teaching the c++ language.

And an also notable blog post

I have a dream ...

I'm dreaming of so called C++ courses/classes/curriculae will stop teaching (requiring) their students to use: ...

Since C++11 as established standard we have the Dynamic memory management facilities aka smart pointers.
Even from earlier standards we have the c++ standard Containers library as a good replacement for raw arrays (allocated with new T[]) (notably usage of std::string instead of c-style NUL terminated character arrays).

Question(s) in bold:

Let aside the placement new override, is there any valid use case that can't be achieved using smart pointers or standard containers but only using new and delete directly (besides implementation of such container/smart pointer classes of course)?

It's sometimes rumored (like here or here) that using new and delete handrolled can be "more efficient" for certain cases. Which are these actually? Don't these edge cases need to keep track of the allocations the same way as standard containers or smart pointers need to do?

Almost the same for raw c-style fixed size arrays: There is std::array nowadays, which allows all kinds of assignment, copying, referencing, etc. easily and syntactically consistent as expected by everyone. Are there any use cases to choose a T myArray[N]; c-style array in preference of std::array<T,N> myArray;?


Regarding interaction with 3rd party libraries:

Assumed a 3rd party library returns raw pointers allocated with new like

MyType* LibApi::CreateNewType() {
    return new MyType(someParams);
}

you can always wrap that to a smart pointer to ensure that delete is called:

std::unique_ptr<MyType> foo = LibApi::CreateNewType();

even if the API requires you to call their legacy function to free the resource like

void LibApi::FreeMyType(MyType* foo);

you still can provide a deleter function:

std::unique_ptr<MyType, LibApi::FreeMyType> foo = LibApi::CreateNewType();

I'm especially interested in valid "every day" use cases in contrast to academic/educational purpose requirements and restrictions, which aren't covered by the mentioned standard facilities.
That new and delete may be used in memory management / garbage collector frameworks or standard container implementation is out of question1.


One major motivation ...

... to ask this question is to give an alternative approach vs any (homework) questions, which are restricted to use any of the constructs mentioned in the title, but serious questions about production ready code.

These are often referred to as the basics of memory management, which is IMO blatantly wrong/misunderstood as suitable for beginners lectures and tasks.


1)Add.: Regarding that paragraph, this should be a clear indicator that new and delete isn't for beginner c++ students, but should be left for the more advanced courses.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When ownership should not be local.

As an example, a pointer container may not want ownership over the pointers in it to reside in the pointers themselves. If you try to write a linked list with forward unique ptrs, at destruction time you can easily blow the stack.

A vector-like container of owning pointers may be better suited to storing delete operation at the container or subcontainer level, and not at the element level.

In those and similar cases, you wrap ownership like a smart pointer does, but you do it at a higher level. Many data structures (graphs, etc) may have similar issues, where ownership properly resides at a higher point than where the pointers are, and they may not map directly to an existing container concept.

In some cases it may be easy to factor out the container-ownership from the rest of the data structure. In others it may not.

Sometimes you have insanely complex non-local non-reference counted lifetimes. There is no sane spot to put the ownership pointer in those cases.

Determining correctness here is hard, but not impossible. Programs that are correct and have such complex ownership semantics exist.


All of these are corner cases, and few programmers should run into them more than a handful of times in a career.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...