Re: why not use naked delete ?
[Please do not mail me a copy of your followup]
arnuld <sunrise@invalid.address> spake the secret code
<549d3f6c$0$280$14726298@news.sunsite.dk> thusly:
After 5 years of working purely in C, finally I becawe jobless and have
some time on my hands to start C++. Well, I kept on peeking into
stroustrup from time to time but now I see with C++14 everything has
changed.
C++14 hardly changes "everything". You can view it mostly as a "minor
enhancement" to C++11.
If by "changes everything" you mean the changes introduced by C++11/14
compared to C++98, I'd still disagree with that statement. As far as
the core language is concerned, C++11/14 make it easier and less
problematic to write C++ code than C++98. Changes (as opposed to
additions) to the standard library weren't that significant IMO.
Even in C++, I will allocate memory using /new/ and then free it
using /delete/ but now I see Stroustrup does not seem to agree to that:
The only time new or delete (almost the lowest-level mechanism for
managing memory) should appear in your code is in a class designed to
manage the resource acquired by new and released by delete. Since the
standard library already provides two resource managing clases for
this purpose, std::unique_ptr and std::shared_ptr, there isn't any
reason you should be using new or delete directly in your code.
Furthermore, since most uses of new/delete have to do with creating
blocks of memory to hold collections of values and the standard
library provides container classes already, there is even less of a
need to use new/delete directly.
Need a variable-length buffer of characters to pass to some C style
function? Use std::vector<char>.
Need a string? Use std::string.
Need a dynamically resizable array of some other type T? Use
std::vector<T>.
Need a dictionary to look up values of type T from strings? Use
std::map<std::string, T>.
[...] I am more
concerned with simple procedural subset of C++:
X* p = new X;
X* q = p;
Well, this is poor form already. Who "owns" the instance of X? p or q?
If you had written:
X* p = new X;
X &q = *p;
// ...
delete p;
q.do_something(); // oops, still a problem.
Then your code would be revealing your intention instead of confusing
the reader. If we use scoping to limit the use of q to only where it
is intended, then we solve the "oops"
X* p = new X;
{
X &q = *p;
// ...
q.do_something();
}
delete p;
Now we've used scoping to explicitly reveal that q has a dependency on
p and that p's lifetime should extend beyond the lifetime of q.
However, we still have a problem if do_something() or anything else in
that block can throw an exception. If an exception is thrown, the
stack is unwound and we've leaked the memory pointed to by p.
I know this is only code you've written for the purposes of
discussion, but let's talk about another thing shown here. Is the use
of the heap really necessary? Why not write:
X p;
X &q = p;
....and then we don't have to worry about whether or not q can still be
used -- its lifetime is guaranteed to be shorter than p's lifetime.
We also don't need to worry about who is responsible for destroying p;
it's destroyed when we leave the scope of p. We also get code that is
exception safe.
We shouldn't use the heap unless it is really necessary.
So how do you get exception-safe use of the heap? First, make sure
you really need the heap (your toy example does not). Second, if you
really must use the heap, consider what you are trying to do with
dynamically allocated memory.
Are you trying to make a container? Use one of the standard library
container classes for that.
Are you trying to extend the lifetime of some data beyond the scope
of the code that creates it? Try std::unique_ptr.
Are you really trying to create shared data structures? Try
std::shared_ptr. (Note: shared data structures can lead to all kinds
of problems and I don't recommend blindly throwing shared_ptr at
everything. Most applications have very few required uses of shared
data, where the data must really be shared.
Use <http://cppreference.com> as your reference to the standard
library classes if you don't have a good book. I like Nicolai
Josuttis "The C++ Standard Library" myself.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>