jl_p...@hotmail.com wrote:
>
> (Now, I understand that it's bad form to allocate memory and free/
delete it in the very same scope,
On Jun 27, 2:08 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>
Why?
jl_p...@hotmail.com wrote:
Because if it's all in the same scope, there's no need to declare
it as a pointer and allocate it memory. Just declare it on the stack
(as a non-pointer) and let it clean itself up.
On Jun 27, 2:08 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>
That would require pretty big stack, for one. OTOH, if it's an array
you want whose size needs to be determined at run-time, you have no
other choice but to use dynamic memory. You have mechanisms that help
you like 'std::vector' or 'std::deque', or you can roll your own, but
those arrays aren't on the stack, that's for sure. And they allocate
their memory and free/delete it in the "very same scope", only without
actually exposing those operations.
You're right, of course. std::vectors and std::strings do use
pointers and memory allocation/deallocation under the hood, but that's
not what Bjarne Stroustrup (and I) want to avoid.
std::string and std::vectors (and other STL containers, I'm sure)
use memory allocation & deallocation, but they do so transparently, so
the programmer who uses them does not have to worry about it. The
containers are written so that they are self-cleaning (in that they
clean themselves when they go out of scope), relieving the programmer
who uses them of having to do any pointer maintenance on them.
When you use a pointer in the way that Stroustrup said you
shouldn't, like this:
void fct() // ugly, error-prone, and inefficient
{
X* p = new X;
// use p
delete p;
}
you have to:
a) remember to delete p at the end of the scope
b) remember to delete p if ever the function is prematurely exited
c) make sure p is never free()d (or deleted if malloc()ed)
and if you do allocate memory for a pointer that is meant to live
outside its scope, you still have to:
d) make it clear whose responsibility it is to free/delete the memory
e) make sure the memory really IS freed/deleted
f) make sure p is never deleted more than once
and if you are a programmer and are dealing with a buggy section of
code that uses a pointer, you still have these potential problems to
consider:
g) you may not necessarily know if the memory you're pointing to was
properly initialized
h) you may not necessarily know if the memory you're pointing to has
already been freed/deleted
i) you won't necessarily know if the pointer you have points to just
one instance of an object, or just the first element of an allocated
array of objects
j) if you have a pointer that you know points to the first element of
an allocated array of objects, you have no way of knowing when you go
out of the array bounds unless the original programmer was kind enough
to provide that information for you
(And for the record, I've seen ALL of these happen, and I've had to
fix all of them at least once.)
But if you use the alternatives C++ provides you (such as
std::strings, std::vectors, references, and declaring objects on the
stack), you'll never have to worry about those issues. For example,
if you avoid the manual memory allocation of an object (using new or
malloc()), you don't have to worry about double-freeing memory -- in
fact, you don't have to worry about de-allocating memory at all! STL
objects (declared on the stack) will do it for you so you don't have
to.
I encourage C++ programmers to avoid using the '*' operator in
their code (unless, of course, it's for multiplication). Doing so
avoids many headaches associated with pointers (like memory leaks and
crashes associated with pointers) as well as simplifies many aspects
of their code (like rarely having a need to write an operator=()
method or destructor for their classes).
Sure, the STL classes often use pointers "under the hood," but they
are used in STL classes transparently so that you don't have to
manipulate the pointers manually. When I encourage C++ programmers
not to use pointers, I don't mean not using classes and structures
that use pointers; I mean only using structures that are self-cleaning
-- and avoiding declaring pointers and manual allocation/deallocation
of memory.
Relying on objects declared on the stack (even if they are STL
containers) and not on manually allocated memory almost always results
in cleaner and less error-prone code. (And in many instances results
in faster, more efficient code as well.)
I hope this clarifies things, Victor.
Have a great weekend!
-- Jean-Luc