delete []

D

David Wilkinson

George said:
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.
 
G

Guest

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 said:
George said:
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.
 
D

David Wilkinson

George said:
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.
 
B

Bo Persson

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
 
S

SvenC

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.
 
G

Guest

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 said:
George said:
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.
 
D

David Wilkinson

George said:
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).
 
G

Guest

Thanks David,


I must buy and read the book "More Effective C++". Your clarification is so
clear.


regards,
George

David Wilkinson said:
George said:
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).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top