467,923 Members | 1,392 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,923 developers. It's quick & easy.

delete []

Hello everyone,
I remembered delete[] is implemented through operator overloading, but I am
not quite clear.

Could anyone recommend some links about how delete[] is implemented so that
I can learn and refresh my memory? :-)
thanks in advance,
George
Oct 30 '07 #1
  • viewed: 1916
Share:
29 Replies
George wrote:
Hello everyone,
I remembered delete[] is implemented through operator overloading, but I am
not quite clear.

Could anyone recommend some links about how delete[] is implemented so that
I can learn and refresh my memory? :-)
George:

delete [] calls the destructor of each of the elements in the array, and
then frees the memory. What else do you need to know?

--
David Wilkinson
Visual C++ MVP
Oct 30 '07 #2
Hi David,
My question is how default delete and delete[] are implemented? And how/why
default delete and delete[] works for any data types, for example, we have a
class Foo, even if we do not implement delete and delete[] operator in class
Foo, we still could use delete[] to free the memory of an array of Foo
instances.

Could you help to describe how delete[] works for any data type please?
There are some default base class or some default delete[] implementation in
std namespace?
regards,
George

"David Wilkinson" wrote:
George wrote:
Hello everyone,
I remembered delete[] is implemented through operator overloading, but I am
not quite clear.

Could anyone recommend some links about how delete[] is implemented so that
I can learn and refresh my memory? :-)

George:

delete [] calls the destructor of each of the elements in the array, and
then frees the memory. What else do you need to know?

--
David Wilkinson
Visual C++ MVP
Oct 30 '07 #3

"George" <Ge****@discussions.microsoft.comwrote in message
news:E0**********************************@microsof t.com...
Hi David,
My question is how default delete and delete[] are implemented? And
how/why
default delete and delete[] works for any data types, for example, we have
a
class Foo, even if we do not implement delete and delete[] operator in
class
Foo, we still could use delete[] to free the memory of an array of Foo
instances.

Could you help to describe how delete[] works for any data type please?
There are some default base class or some default delete[] implementation
in
std namespace?
Any type that doesn't provide its own definition of new and delete (and the
array variations) will use the ones belonging to the base class (if it has
them) or else defined in the global (just :: not ::global) namespace.

Many runtime libraries provide different definitions that may do debug
tracing of allocations, etc.

If you tell us what library you are using probably someone can tell you what
file has the default definition of ::operator[]
>

regards,
George

"David Wilkinson" wrote:
>George wrote:
Hello everyone,
I remembered delete[] is implemented through operator overloading, but
I am
not quite clear.

Could anyone recommend some links about how delete[] is implemented so
that
I can learn and refresh my memory? :-)

George:

delete [] calls the destructor of each of the elements in the array, and
then frees the memory. What else do you need to know?

--
David Wilkinson
Visual C++ MVP

Oct 30 '07 #4
Thanks Ben!
I appreciate for your kindness on helping this. I am using Visual Studio
2005 and developing C++.

I want to learn,

1. how delete[] is implemented in my environment (I suspect std::delete[] is
used and it will call destructor of each element in the array)?
2. why if we use new[] to allocate memory, then use delete (other than
delete[]) will cause memory leak?
3. why there is a common delete[] which suits for all various types of
object (I ask this question because I always do not overload operator delete
in my class and delete[] always works)?
regards,
George

"Ben Voigt [C++ MVP]" wrote:
>
"George" <Ge****@discussions.microsoft.comwrote in message
news:E0**********************************@microsof t.com...
Hi David,
My question is how default delete and delete[] are implemented? And
how/why
default delete and delete[] works for any data types, for example, we have
a
class Foo, even if we do not implement delete and delete[] operator in
class
Foo, we still could use delete[] to free the memory of an array of Foo
instances.

Could you help to describe how delete[] works for any data type please?
There are some default base class or some default delete[] implementation
in
std namespace?

Any type that doesn't provide its own definition of new and delete (and the
array variations) will use the ones belonging to the base class (if it has
them) or else defined in the global (just :: not ::global) namespace.

Many runtime libraries provide different definitions that may do debug
tracing of allocations, etc.

If you tell us what library you are using probably someone can tell you what
file has the default definition of ::operator[]


regards,
George

"David Wilkinson" wrote:
George wrote:
Hello everyone,
I remembered delete[] is implemented through operator overloading, but
I am
not quite clear.

Could anyone recommend some links about how delete[] is implemented so
that
I can learn and refresh my memory? :-)

George:

delete [] calls the destructor of each of the elements in the array, and
then frees the memory. What else do you need to know?

--
David Wilkinson
Visual C++ MVP


Oct 31 '07 #5
George wrote:
Thanks Ben!
I appreciate for your kindness on helping this. I am using Visual Studio
2005 and developing C++.

I want to learn,

1. how delete[] is implemented in my environment (I suspect std::delete[] is
used and it will call destructor of each element in the array)?
2. why if we use new[] to allocate memory, then use delete (other than
delete[]) will cause memory leak?
3. why there is a common delete[] which suits for all various types of
object (I ask this question because I always do not overload operator delete
in my class and delete[] always works)?
George:

When you call delete [], the compiler knows both the type of the object
and the number of objects that were allocated. Thus it has all the
information it needs to call *all* the destructors and free the memory.
No overload of operator delete [] is required.

When you call plain delete, the required behavior is to call *one*
destructor and free the memory. If the memory was allocated with new [],
and the objects themselves contain allocated memory, that memory is
leaked for the objects beyond the first. It is possible, I think, that a
compiler could implement delete so that it worked like delete [], but
this is not required by the standard.

The C++ standard says that memory allocated with new must be freed with
delete, and memory allocated with new [] must be freed with delete [].
Anything else is undefined behavior.

--
David Wilkinson
Visual C++ MVP
Oct 31 '07 #6
Can one also free up memory allocated my 'gcnew' manually, or if you will,
when one desires (in contrast to letting the gc pick when)? If so, what does
one use (I'm assuming delete and delete[] won't work)...

[==Peter==]

"David Wilkinson" <no******@effisols.comwrote in message
news:uE**************@TK2MSFTNGP02.phx.gbl...
George wrote:
>Thanks Ben!
I appreciate for your kindness on helping this. I am using Visual Studio
2005 and developing C++.

I want to learn,

1. how delete[] is implemented in my environment (I suspect std::delete[]
is used and it will call destructor of each element in the array)?
2. why if we use new[] to allocate memory, then use delete (other than
delete[]) will cause memory leak?
3. why there is a common delete[] which suits for all various types of
object (I ask this question because I always do not overload operator
delete in my class and delete[] always works)?

George:

When you call delete [], the compiler knows both the type of the object
and the number of objects that were allocated. Thus it has all the
information it needs to call *all* the destructors and free the memory. No
overload of operator delete [] is required.

When you call plain delete, the required behavior is to call *one*
destructor and free the memory. If the memory was allocated with new [],
and the objects themselves contain allocated memory, that memory is leaked
for the objects beyond the first. It is possible, I think, that a compiler
could implement delete so that it worked like delete [], but this is not
required by the standard.

The C++ standard says that memory allocated with new must be freed with
delete, and memory allocated with new [] must be freed with delete [].
Anything else is undefined behavior.

--
David Wilkinson
Visual C++ MVP

Oct 31 '07 #7
George wrote:
:: Thanks Ben!
::
::
:: I appreciate for your kindness on helping this. I am using Visual
:: Studio 2005 and developing C++.
::
:: I want to learn,
::
:: 1. how delete[] is implemented in my environment (I suspect
:: std::delete[] is used and it will call destructor of each element
:: in the array)?

No, it is not std::delete[], it is actually two different parts of the
language (with unfortunate names).

The delete[] statement, and the operator delete[].

When you write

delete[] ptr;

the compiler will turn this staement into a sequence of

a) calls the destructor for each element in the array
b) calls operator delete[](ptr)

If you haven't added an overload for your type, there is always a
global

void operator delete[](void* _Ptr) throw();

that the compiler can call.

:: 2. why if we use new[] to allocate memory, then use delete (other
:: than delete[]) will cause memory leak?

It might, or it might not. The rules of the language say that delete[]
must call all destructors, delete doesn't have to.

The intent is obviously that plain delete is used more often, and that
it possibly can run slightly faster if it doesn't have to figure out
the number of elements in the array. It can assume 1 always.

Probably doesn't make much difference in practice, but that's the way
it is.

:: 3. why there is a common delete[] which suits for all various
:: types of object (I ask this question because I always do not
:: overload operator delete in my class and delete[] always works)?

There is a global operator delete[], just like there is a global
operator new[]. The compiler sets proper parameter values from the
type info it has.

Bo Persson
Oct 31 '07 #8
Peter Oliphant wrote:
Can one also free up memory allocated my 'gcnew' manually, or if you
will, when one desires (in contrast to letting the gc pick when)? If
so, what does one use (I'm assuming delete and delete[] won't work)...
Basically, no. You can call GC::Collect(), but it's rarely a good idea to
do so.

-cd
Nov 1 '07 #9
Thanks Dave,
Your reply is very helpful. I am wondering if we do not implement
(overwrite) delete and delete[] in our class, there should be a default
implementation of delete and delete[] for all data types -- including our own
data types (class).

If I am using Visual Studio 2005, where is the default implementation? In
some default namespace (e.g. std) or some global function or in some default
base class?
regards,
George

"David Wilkinson" wrote:
George wrote:
Thanks Ben!
I appreciate for your kindness on helping this. I am using Visual Studio
2005 and developing C++.

I want to learn,

1. how delete[] is implemented in my environment (I suspect std::delete[] is
used and it will call destructor of each element in the array)?
2. why if we use new[] to allocate memory, then use delete (other than
delete[]) will cause memory leak?
3. why there is a common delete[] which suits for all various types of
object (I ask this question because I always do not overload operator delete
in my class and delete[] always works)?

George:

When you call delete [], the compiler knows both the type of the object
and the number of objects that were allocated. Thus it has all the
information it needs to call *all* the destructors and free the memory.
No overload of operator delete [] is required.

When you call plain delete, the required behavior is to call *one*
destructor and free the memory. If the memory was allocated with new [],
and the objects themselves contain allocated memory, that memory is
leaked for the objects beyond the first. It is possible, I think, that a
compiler could implement delete so that it worked like delete [], but
this is not required by the standard.

The C++ standard says that memory allocated with new must be freed with
delete, and memory allocated with new [] must be freed with delete [].
Anything else is undefined behavior.

--
David Wilkinson
Visual C++ MVP
Nov 1 '07 #10
Thanks Dave,
Your reply is very helpful. I am wondering if we do not implement
(overwrite) delete and delete[] in our class, there should be a default
implementation of delete and delete[] for all data types -- including our own
data types (class).

If I am using Visual Studio 2005, where is the default implementation? In
some default namespace (e.g. std) or some global function or in some default
base class?
regards,
George

"David Wilkinson" wrote:
George wrote:
Thanks Ben!
I appreciate for your kindness on helping this. I am using Visual Studio
2005 and developing C++.

I want to learn,

1. how delete[] is implemented in my environment (I suspect std::delete[] is
used and it will call destructor of each element in the array)?
2. why if we use new[] to allocate memory, then use delete (other than
delete[]) will cause memory leak?
3. why there is a common delete[] which suits for all various types of
object (I ask this question because I always do not overload operator delete
in my class and delete[] always works)?

George:

When you call delete [], the compiler knows both the type of the object
and the number of objects that were allocated. Thus it has all the
information it needs to call *all* the destructors and free the memory.
No overload of operator delete [] is required.

When you call plain delete, the required behavior is to call *one*
destructor and free the memory. If the memory was allocated with new [],
and the objects themselves contain allocated memory, that memory is
leaked for the objects beyond the first. It is possible, I think, that a
compiler could implement delete so that it worked like delete [], but
this is not required by the standard.

The C++ standard says that memory allocated with new must be freed with
delete, and memory allocated with new [] must be freed with delete [].
Anything else is undefined behavior.

--
David Wilkinson
Visual C++ MVP
Nov 1 '07 #11
Thanks Bo,
Your answer is comprehensive!

Two more comments,

1. about where is the global delete[]
There is a global operator delete[], just like there is a global
operator new[]. The compiler sets proper parameter values from the
type info it has.
I am wondering where is the global delete[] you mentioned. In some global
namespace (e.g. std?), some global default base class or somewhere else?
Suppose I am using Visual Studio 2005 to develop C++.

2. about step b of the sequences
a) calls the destructor for each element in the array
b) calls operator delete[](ptr)
I can understand step a, but can not understand why step b is needed? I have
this question because I think step a is enough and why need step b (I think
if delete[] could trigger each destructor of instance of the instance array,
it should be enough)? Could you describe what is step b doing for example
please?
regards,
George

"Bo Persson" wrote:
George wrote:
:: Thanks Ben!
::
::
:: I appreciate for your kindness on helping this. I am using Visual
:: Studio 2005 and developing C++.
::
:: I want to learn,
::
:: 1. how delete[] is implemented in my environment (I suspect
:: std::delete[] is used and it will call destructor of each element
:: in the array)?

No, it is not std::delete[], it is actually two different parts of the
language (with unfortunate names).

The delete[] statement, and the operator delete[].

When you write

delete[] ptr;

the compiler will turn this staement into a sequence of

a) calls the destructor for each element in the array
b) calls operator delete[](ptr)

If you haven't added an overload for your type, there is always a
global

void operator delete[](void* _Ptr) throw();

that the compiler can call.

:: 2. why if we use new[] to allocate memory, then use delete (other
:: than delete[]) will cause memory leak?

It might, or it might not. The rules of the language say that delete[]
must call all destructors, delete doesn't have to.

The intent is obviously that plain delete is used more often, and that
it possibly can run slightly faster if it doesn't have to figure out
the number of elements in the array. It can assume 1 always.

Probably doesn't make much difference in practice, but that's the way
it is.

:: 3. why there is a common delete[] which suits for all various
:: types of object (I ask this question because I always do not
:: overload operator delete in my class and delete[] always works)?

There is a global operator delete[], just like there is a global
operator new[]. The compiler sets proper parameter values from the
type info it has.

Bo Persson
Nov 1 '07 #12
George wrote:
Thanks Bo,
Your answer is comprehensive!

Two more comments,

1. about where is the global delete[]
>There is a global operator delete[], just like there is a global
operator new[]. The compiler sets proper parameter values from the
type info it has.

I am wondering where is the global delete[] you mentioned. In some global
namespace (e.g. std?), some global default base class or somewhere else?
Suppose I am using Visual Studio 2005 to develop C++.

2. about step b of the sequences
>a) calls the destructor for each element in the array
b) calls operator delete[](ptr)

I can understand step a, but can not understand why step b is needed? I have
this question because I think step a is enough and why need step b (I think
if delete[] could trigger each destructor of instance of the instance array,
it should be enough)? Could you describe what is step b doing for example
please?
George:

Because under the hood, a call to new [] incurs a call to malloc(). So
delete [] has to call free() to release the memory.

--
David Wilkinson
Visual C++ MVP
Nov 1 '07 #13

"George" <Ge****@discussions.microsoft.comwrote in message
news:04**********************************@microsof t.com...
Thanks Dave,
Your reply is very helpful. I am wondering if we do not implement
(overwrite) delete and delete[] in our class, there should be a default
implementation of delete and delete[] for all data types -- including our
own
data types (class).

If I am using Visual Studio 2005, where is the default implementation? In
some default namespace (e.g. std) or some global function or in some
default
base class?
It is in the global namespace. C++ does not have default namespaces. C++
does not have default base classes.

If you are using the Microsoft C++ runtime library (you can replace this
independent of the compiler), then it can be found in:

C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\delete2.cpp

which is compiled into MSVCRT80.dll or statically linked into your program
(I think the name is libcmt.lib), depending on your project options.
Nov 1 '07 #14
Cool. Actually, kind of a relief. That means I must rely on the GC, so I
don't have to really worry about freeing up memory since basically I'm not
'allowed' to.

I truly feel GC was a necessary feature. Most of my old progrmas truly
suffered from trying to figure out when to delete stuff, since it is often
the case a particualr class instance has no idea if something else external
to it is also using the memory. I can think of scenarios where is almost
impossible.

The old solution use to be to just allocate all of memory and write one's
own memory allocator by portioning it out. That way one could be aware at
that level if anything was still referencing it, and more important, could
easily free up all allocated memory upon exit by just freeing up the big
block it initially allocated and then portioned out (i.e., no memory leaks
upon exit).

But that IS in affect GC, so it is good this is now available to users of VS
C++ without having to write it as custom layer...

[==Peter==]

"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:up****************@TK2MSFTNGP04.phx.gbl...
Peter Oliphant wrote:
>Can one also free up memory allocated my 'gcnew' manually, or if you
will, when one desires (in contrast to letting the gc pick when)? If
so, what does one use (I'm assuming delete and delete[] won't work)...

Basically, no. You can call GC::Collect(), but it's rarely a good idea to
do so.

-cd


Nov 1 '07 #15
Hi Ben,
Global namespace you mean namespace std?
regards,
George

"Ben Voigt [C++ MVP]" wrote:
>
"George" <Ge****@discussions.microsoft.comwrote in message
news:04**********************************@microsof t.com...
Thanks Dave,
Your reply is very helpful. I am wondering if we do not implement
(overwrite) delete and delete[] in our class, there should be a default
implementation of delete and delete[] for all data types -- including our
own
data types (class).

If I am using Visual Studio 2005, where is the default implementation? In
some default namespace (e.g. std) or some global function or in some
default
base class?

It is in the global namespace. C++ does not have default namespaces. C++
does not have default base classes.

If you are using the Microsoft C++ runtime library (you can replace this
independent of the compiler), then it can be found in:

C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\delete2.cpp

which is compiled into MSVCRT80.dll or statically linked into your program
(I think the name is libcmt.lib), depending on your project options.
Nov 2 '07 #16
Hi Dave,
I have two questions below, Your answer,
Because under the hood, a call to new [] incurs a call to malloc(). So
delete [] has to call free() to release the memory.
is for which question. Sorry that I am a little confused. :-)
have a good weekend,
George

"David Wilkinson" wrote:
George wrote:
Thanks Bo,
Your answer is comprehensive!

Two more comments,

1. about where is the global delete[]
There is a global operator delete[], just like there is a global
operator new[]. The compiler sets proper parameter values from the
type info it has.
I am wondering where is the global delete[] you mentioned. In some global
namespace (e.g. std?), some global default base class or somewhere else?
Suppose I am using Visual Studio 2005 to develop C++.

2. about step b of the sequences
a) calls the destructor for each element in the array
b) calls operator delete[](ptr)
I can understand step a, but can not understand why step b is needed? I have
this question because I think step a is enough and why need step b (I think
if delete[] could trigger each destructor of instance of the instance array,
it should be enough)? Could you describe what is step b doing for example
please?

George:

Because under the hood, a call to new [] incurs a call to malloc(). So
delete [] has to call free() to release the memory.

--
David Wilkinson
Visual C++ MVP
Nov 2 '07 #17
George wrote:
Hi Dave,
I have two questions below, Your answer,
>Because under the hood, a call to new [] incurs a call to malloc(). So
delete [] has to call free() to release the memory.

is for which question. Sorry that I am a little confused. :-)
George:

Obviously, for your second question. You asked why it is necessary to
call operator delete [](ptr).

When you use new []

The memory is created by operator new [] (which uses malloc() by default)
Default constructors are called to create the objects

So when you call delete []

Destructors are called to clean up the objects
The memory is freed by operator delete [] (which uses free() by default)

Makes sense, no?

--
David Wilkinson
Visual C++ MVP
Nov 2 '07 #18
Thanks David,
Now I understand why I am confused. You mentioned,
Destructors are called to clean up the objects
The memory is freed by operator delete [] (which uses free() by default)
I think destructor itself could free the memory (please correct me if I am
not correct at this point), so there is no need to call operator delete[] to
free the memory again? :-)

If destructor could free memory occupied by the instances and delete[]
operator must free some other memory. :-)

Any comments?
regards,
George

"David Wilkinson" wrote:
George wrote:
Hi Dave,
I have two questions below, Your answer,
Because under the hood, a call to new [] incurs a call to malloc(). So
delete [] has to call free() to release the memory.
is for which question. Sorry that I am a little confused. :-)

George:

Obviously, for your second question. You asked why it is necessary to
call operator delete [](ptr).

When you use new []

The memory is created by operator new [] (which uses malloc() by default)
Default constructors are called to create the objects

So when you call delete []

Destructors are called to clean up the objects
The memory is freed by operator delete [] (which uses free() by default)

Makes sense, no?

--
David Wilkinson
Visual C++ MVP
Nov 2 '07 #19
Hi George,
Global namespace you mean namespace std?
No. If Ben would have wanted to say "namespace std", then he would have
written "namespace std". But he wrote global and meant global. In fact he
did specify that in his first answer. Please see the relevant part cited
here:
any type that doesn't provide its own definition of new
and delete (and the array variations) will use the ones
belonging to the base class (if it has them) or else
defined in the global (just :: not ::global) namespace.
The global namespace can be seen as the namespace without name. If you want
to address a symbol of the global namespace you can do that by prepending ::
before that symbol. If you e.g. put a function min in some header without
putting it into a namespace and in some code you include that header and
also use <algorithmand put a "using namespace std;" in your code, both min
functions are available and you will need to either use ::min or std::min
BTW and OT: you ask so many C++ beginner level questions in different news
groups. Did you ever think about buying a book? You might find some here:
http://www.accu.org

There is also a C++ FAQ at: http://www.parashift.com/c++-faq-lite

--
SvenC

Nov 2 '07 #20
George wrote:
Thanks David,
Now I understand why I am confused. You mentioned,
>Destructors are called to clean up the objects
The memory is freed by operator delete [] (which uses free() by default)

I think destructor itself could free the memory (please correct me if I am
not correct at this point), so there is no need to call operator delete[] to
free the memory again? :-)

If destructor could free memory occupied by the instances and delete[]
operator must free some other memory. :-)

Any comments?
George:

Yes. You are wrong. Every malloc() must have a free(). The destructors
of the individual objects cannot free the memory that was created for
the whole array by new [], because they do not know anything about it.

Destructors are not only called for objects allocated on the heap; they
are also called for objects on the stack.

--
David Wilkinson
Visual C++ MVP
Nov 2 '07 #21
Thanks SvenC,
I have checked http://www.accu.org, it is a not a web site which sells books
with discount, right? :-)
regards,
George

"SvenC" wrote:
Hi George,
Global namespace you mean namespace std?

No. If Ben would have wanted to say "namespace std", then he would have
written "namespace std". But he wrote global and meant global. In fact he
did specify that in his first answer. Please see the relevant part cited
here:
any type that doesn't provide its own definition of new
and delete (and the array variations) will use the ones
belonging to the base class (if it has them) or else
defined in the global (just :: not ::global) namespace.

The global namespace can be seen as the namespace without name. If you want
to address a symbol of the global namespace you can do that by prepending ::
before that symbol. If you e.g. put a function min in some header without
putting it into a namespace and in some code you include that header and
also use <algorithmand put a "using namespace std;" in your code, both min
functions are available and you will need to either use ::min or std::min
BTW and OT: you ask so many C++ beginner level questions in different news
groups. Did you ever think about buying a book? You might find some here:
http://www.accu.org

There is also a C++ FAQ at: http://www.parashift.com/c++-faq-lite

--
SvenC
Nov 3 '07 #22
Hi David,
Sorry for my confusion again. :-)

I will show you a sample. Suppose I have a class Foo and in this class
(constructor), I malloc 10 bytes, and in the destructor of this class I will
call free to release the 10 bytes.

Suppose some other components use new Foo[5] to malloc 10 * 5 = 50 bytes and
5 instances of Foo, then when we call delete[] with the pointer to Foo[5] we
malloced before, then the destructor will be invoked 5 times, and in each
time, 10 bytes will be freed (released). So the memory is balanced, right?

So, in my points, I think in delete[] implementation, invoking the
destructor for each instances is enough (see my sample above). I think I may
not correct and you are more experienced. But from the sample, I can not make
myself convinced about why you mentioned an additonal step should be used to
free the memory of the array?
regards,
George

"David Wilkinson" wrote:
George wrote:
Thanks David,
Now I understand why I am confused. You mentioned,
Destructors are called to clean up the objects
The memory is freed by operator delete [] (which uses free() by default)
I think destructor itself could free the memory (please correct me if I am
not correct at this point), so there is no need to call operator delete[] to
free the memory again? :-)

If destructor could free memory occupied by the instances and delete[]
operator must free some other memory. :-)

Any comments?

George:

Yes. You are wrong. Every malloc() must have a free(). The destructors
of the individual objects cannot free the memory that was created for
the whole array by new [], because they do not know anything about it.

Destructors are not only called for objects allocated on the heap; they
are also called for objects on the stack.

--
David Wilkinson
Visual C++ MVP
Nov 3 '07 #23
George wrote:
Hi David,
Sorry for my confusion again. :-)

I will show you a sample. Suppose I have a class Foo and in this class
(constructor), I malloc 10 bytes, and in the destructor of this class I will
call free to release the 10 bytes.

Suppose some other components use new Foo[5] to malloc 10 * 5 = 50 bytes and
5 instances of Foo, then when we call delete[] with the pointer to Foo[5] we
malloced before, then the destructor will be invoked 5 times, and in each
time, 10 bytes will be freed (released). So the memory is balanced, right?

So, in my points, I think in delete[] implementation, invoking the
destructor for each instances is enough (see my sample above). I think I may
not correct and you are more experienced. But from the sample, I can not make
myself convinced about why you mentioned an additonal step should be used to
free the memory of the array?
George:

I would strongly recommend that you read Scott Myers' "More Effective
C++", which has a good discussion of the difference between the "new
operator" and "operator new", and friends, and how to implement the latter.

Basically:

The new operator calls operator new to create the memory and then
constructs the object in that space.

The delete operator calls the destructor, and then calls operator delete
to free the memory.

You have no control over the new operator and delete operator; they are
part of the language. What you can control is the implementation of
operator new and operator delete. The default versions use malloc() and
free().

Likewise the [] forms of these.

You see that the separation of the object creation/destruction from the
memory creation/destruction is an intrinsic part of the C++ language,
and there is no point in discussing how it might be different.

If you provide your own new and delete operators (and [] forms) to
handle the memory part, then it is up to you to make sure that, as a
pair, they do not leak memory.

As others have mentioned, this question should have been asked in
microsoft.public.vc.language, because it has nothing to do with .NET.

--
David Wilkinson
Visual C++ MVP
Nov 3 '07 #24
George wrote:
:: Thanks SvenC,
::
::
:: I have checked http://www.accu.org, it is a not a web site which
:: sells books with discount, right? :-)
::

No, it's not.

But if you look in the Book Reviews section, you will find lot's of
books reviewed by IT professionals and listed from Exceptionally good
to Just crap.

If you buy some books marked Highly Recommended, you just cannot go
wrong. The "discount" part is that you can avoid buying the books at
the bottom of the list!
Bo Persson
Nov 3 '07 #25
Hi George,
I have checked http://www.accu.org, it is a not a web site which sells
books
with discount, right? :-)
No, it is a site with book reviews to help you decide which one to buy at
your favorite book store.
Just click on "Book reviews" and search for C++ and maybe some other words
of interest like STL or COM.

--
SvenC

Nov 3 '07 #26
Thanks Bo Persson,
Your answer is very clear!
regards,
George

"Bo Persson" wrote:
George wrote:
:: Thanks SvenC,
::
::
:: I have checked http://www.accu.org, it is a not a web site which
:: sells books with discount, right? :-)
::

No, it's not.

But if you look in the Book Reviews section, you will find lot's of
books reviewed by IT professionals and listed from Exceptionally good
to Just crap.

If you buy some books marked Highly Recommended, you just cannot go
wrong. The "discount" part is that you can avoid buying the books at
the bottom of the list!
Bo Persson
Nov 3 '07 #27
Thanks David,
The last question,

I want to confirm with you after reading your reply,

1. when invoke delete (without []), the destructor will be invoked and then
the global delete operator will be invoked (as default);
2. when invoke delete[], the destructor for each instance element of the
array will be invoked and then the global delete operator will be invoked (as
default), and the global delete operator is the same in (1).

Right?
regards,
George

"David Wilkinson" wrote:
George wrote:
Hi David,
Sorry for my confusion again. :-)

I will show you a sample. Suppose I have a class Foo and in this class
(constructor), I malloc 10 bytes, and in the destructor of this class I will
call free to release the 10 bytes.

Suppose some other components use new Foo[5] to malloc 10 * 5 = 50 bytes and
5 instances of Foo, then when we call delete[] with the pointer to Foo[5] we
malloced before, then the destructor will be invoked 5 times, and in each
time, 10 bytes will be freed (released). So the memory is balanced, right?

So, in my points, I think in delete[] implementation, invoking the
destructor for each instances is enough (see my sample above). I think I may
not correct and you are more experienced. But from the sample, I can not make
myself convinced about why you mentioned an additonal step should be used to
free the memory of the array?

George:

I would strongly recommend that you read Scott Myers' "More Effective
C++", which has a good discussion of the difference between the "new
operator" and "operator new", and friends, and how to implement the latter.

Basically:

The new operator calls operator new to create the memory and then
constructs the object in that space.

The delete operator calls the destructor, and then calls operator delete
to free the memory.

You have no control over the new operator and delete operator; they are
part of the language. What you can control is the implementation of
operator new and operator delete. The default versions use malloc() and
free().

Likewise the [] forms of these.

You see that the separation of the object creation/destruction from the
memory creation/destruction is an intrinsic part of the C++ language,
and there is no point in discussing how it might be different.

If you provide your own new and delete operators (and [] forms) to
handle the memory part, then it is up to you to make sure that, as a
pair, they do not leak memory.

As others have mentioned, this question should have been asked in
microsoft.public.vc.language, because it has nothing to do with .NET.

--
David Wilkinson
Visual C++ MVP
Nov 3 '07 #28
George wrote:
Thanks David,
The last question,

I want to confirm with you after reading your reply,

1. when invoke delete (without []), the destructor will be invoked and then
the global delete operator will be invoked (as default);
2. when invoke delete[], the destructor for each instance element of the
array will be invoked and then the global delete operator will be invoked (as
default), and the global delete operator is the same in (1).

Right?
George:

According to Scott Myers book, you are using the words wrong. The delete
operator is the one you call from your code. Operator delete is the one
that gets called after the destructor has been called; it the latter
that you can override (must override together with operator new).

Likewise for the [] versions.

It may or may not be true that operator new/delete are the same as
operator new/delete []. This depends on the implementation (your
implementation if you choose to override).

--
David Wilkinson
Visual C++ MVP
Nov 3 '07 #29
Thanks David,
I must buy and read the book "More Effective C++". Your clarification is so
clear.
regards,
George

"David Wilkinson" wrote:
George wrote:
Thanks David,
The last question,

I want to confirm with you after reading your reply,

1. when invoke delete (without []), the destructor will be invoked and then
the global delete operator will be invoked (as default);
2. when invoke delete[], the destructor for each instance element of the
array will be invoked and then the global delete operator will be invoked (as
default), and the global delete operator is the same in (1).

Right?

George:

According to Scott Myers book, you are using the words wrong. The delete
operator is the one you call from your code. Operator delete is the one
that gets called after the destructor has been called; it the latter
that you can override (must override together with operator new).

Likewise for the [] versions.

It may or may not be true that operator new/delete are the same as
operator new/delete []. This depends on the implementation (your
implementation if you choose to override).

--
David Wilkinson
Visual C++ MVP
Nov 4 '07 #30

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Dave | last post: by
1 post views Thread by Nimmi Srivastav | last post: by
3 posts views Thread by Nimmi Srivastav | last post: by
1 post views Thread by Douglas Peterson | last post: by
2 posts views Thread by Dave | last post: by
3 posts views Thread by silver360 | last post: by
9 posts views Thread by rohits123 | last post: by
10 posts views Thread by jeffjohnson_alpha | last post: by
15 posts views Thread by LuB | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.