By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,321 Members | 1,875 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,321 IT Pros & Developers. It's quick & easy.

making sure that the deallocated dynamically memory returns to the heap?

P: n/a
Hello All,

I was asked a question in an interview..

Its related to dynamically allocated and deallocated memory.

eg.
//start
char * p = new char[1000];
...
....
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?
I answered make p = NULL.But again the interviewer was probably
expecting different answer as the debate went on thereafter...

So for me my knoweldge about dynamically allocated and deallocated
memroy starts with new and ends with delete...
So is there any such thing like making sure that the deallocated(or
freeed) memory is returned to the heap?

Thanks and Regards,
Yogesh
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 20 '06 #1
Share this Question
Share on Google+
37 Replies


P: n/a
As far as I know, after calling delete[]p memory is automaticly returned to
heap. So, this is responsibility of operator delete (and []).

Maybe this was one of trick-questions?

Best,
Zaharije Pasalic

Jan 20 '06 #2

P: n/a
[Cross-posting deleted]

yo******@gmail.com wrote:
Hello All,

I was asked a question in an interview..

Its related to dynamically allocated and deallocated memory.

eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?
I answered make p = NULL.But again the interviewer was probably
expecting different answer as the debate went on thereafter...

So for me my knoweldge about dynamically allocated and deallocated
memroy starts with new and ends with delete...
So is there any such thing like making sure that the deallocated(or
freeed) memory is returned to the heap?


If the code makes it to the delete[] statement and the address held by
p has not been changed, it will certainly be freed (or "returned to the
heap") unless the global new[] and delete[] operators were overloaded
to do something different than the usual operators. Making the pointer
NULL afterwards has no effect on the heap, but it is good practice if
the pointer is still in scope in subsequent code.

So, you'll want to make sure new[] and delete[] are not overloaded,
make p a "char*const" instead of "char*", and make sure no exceptions
are thrown in the "..." region. Better still would be to use a smart
pointer to handle all allocated memory so you don't forget to release
it and so the code is exception-safe.
Cheers! --M

Jan 20 '06 #3

P: n/a
mlimber wrote:
[Cross-posting deleted]

yo******@gmail.com wrote:
Hello All,

I was asked a question in an interview..

Its related to dynamically allocated and deallocated memory.

eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?
I answered make p = NULL.But again the interviewer was probably
expecting different answer as the debate went on thereafter...

So for me my knoweldge about dynamically allocated and deallocated
memroy starts with new and ends with delete...
So is there any such thing like making sure that the deallocated(or
freeed) memory is returned to the heap?
If the code makes it to the delete[] statement and the address held by
p has not been changed, it will certainly be freed (or "returned to the
heap") unless the global new[] and delete[] operators were overloaded
to do something different than the usual operators. Making the pointer
NULL afterwards has no effect on the heap, but it is good practice if
the pointer is still in scope in subsequent code.


I'd say it's not generally good practice, because it might hide double
deletion errors.
So, you'll want to make sure new[] and delete[] are not overloaded,
make p a "char*const" instead of "char*", and make sure no exceptions
are thrown in the "..." region.
In addition, there should of course be no return statement in between, and
if the new[] and delete[] are inside a loop, no continue or break.
Better still would be to use a smart pointer to handle all allocated
memory so you don't forget to release it and so the code is
exception-safe.


For the above example, something similar to std::auto_ptr, but for arrays
would be a good candidate.

Jan 20 '06 #4

P: n/a
On 20 Jan 2006 05:29:51 -0800, "mlimber" <ml*****@gmail.com> wrote:
make p a "char*const" instead of "char*"


Why?

--
Bob Hairgrove
No**********@Home.com
Jan 20 '06 #5

P: n/a
Bob Hairgrove <in*****@bigfoot.com> wrote:
On 20 Jan 2006 05:29:51 -0800, "mlimber" <ml*****@gmail.com> wrote:
make p a "char*const" instead of "char*"


Why?


I imagine it's to avoid a situation like:

p = new char[1000];
++p;
delete [] p;

which is probably UB, since the address passed to delete[] is no longer
the address obtained from new[].

--
Marcus Kwok
Jan 20 '06 #6

P: n/a
In article <dq*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote:
Better still would be to use a smart pointer to handle all allocated
memory so you don't forget to release it and so the code is
exception-safe.


For the above example, something similar to std::auto_ptr, but for arrays
would be a good candidate.


Such a construct is unnecessary. A vector would do the job just fine.
Jan 20 '06 #7

P: n/a

yo******@gmail.com wrote:
Hello All,

I was asked a question in an interview..

Its related to dynamically allocated and deallocated memory.

eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?
By ensuring that every new has a matching delete and every new [] has a
matching delete []. As this code appears to do.
I answered make p = NULL.
That is irrelevant to memory management. You might want to do that if
you are going to keep the pointer and use it again later.
But again the interviewer was probably
expecting different answer as the debate went on thereafter...

So for me my knoweldge about dynamically allocated and deallocated
memroy starts with new and ends with delete...
So is there any such thing like making sure that the deallocated(or
freeed) memory is returned to the heap?


Matching every new and new [] with delete and delete [] respectively is
all you need to do to ensure dynamically allocated memory is freed. But
you do need to make sure the delete happens. You must be sure that the
.... section of your code can't cause the delete [] to be bypassed, e.g.
returning early if this code is in a function, throwing an exception,
or something horrid like a goto. If the code changed the pointer value
without saving it you wouldn't be able to free the memory either. But
then, unless the pointer was changed to point to some other chunk of
memory allocated with new [], the delete [] would yield undefined
behaviour.

There could be issues around overloading new and delete too, but I'm
not sure what the probelms might be.

Gavin Deane
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 20 '06 #8

P: n/a
yo******@gmail.com wrote:
I was asked a question in an interview.. Its related to dynamically allocated and deallocated memory. eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end The quesiton was..How will I be sure the deallocated memory is
returned to heap? I answered make p = NULL.But again the interviewer was
probably expecting different answer as the debate went on
thereafter...
The correct answer is that you can't, since some could have
replaced the operator delete[] function with one which is a
no-op. But I'm willing to bet that this wasn't the answer they
were looking for.:-)

The correct answer, of course, would be to write:
std::vector< char > array( 1000 ) ;
char * p = &array[ 0 ] ;
and skip the delete.

If for some reason you can't use std::vector, then using
boost::scoped_array<char> instead of char* would be a solution.

Given the question, I somehow doubt that this is what they were
looking for either. Which means that I probably wouldn't have
passed their test either.

Look at the bright side: you don't want to work at a place which
asks such dumb questions anyway.
So for me my knoweldge about dynamically allocated and
deallocated memroy starts with new and ends with delete...
Which is already more than you need. If you are using the Boehm
collector, that's ALL you need. If not, you also need to know
about boost::shared_ptr and its collegues (as well as
std::auto_ptr) -- assign the results of new to one of those, and
that's it.

About the only exception is in the implementation of the
smart pointers themselves (but unless you're a real expert,
leave that to Boost), or possibly in a few simple cases like the
compilation firewall idiom (where the management is so simple
that even the simplest smart pointer might be overkill -- and
even then, boost::scoped_ptr would seem a good solution).
So is there any such thing like making sure that the
deallocated(or freeed) memory is returned to the heap?


Well, ignoring for the moment that some one might have replaced
the global operator delete...

Use garbage collection or smart pointers. There ain't no other
way. (In the original example, think of what would hapen if
some function threw an exception between your new and your
delete.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 20 '06 #9

P: n/a
yo******@gmail.com wrote:
I was asked a question in an interview..

Its related to dynamically allocated and deallocated memory.

eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?
Depends on what you mean by "heap". This term is not used in the
Standard C++ in any context related to memory management.

Basically, after calling delete [] p; above, the memory id deallocated.
It is therefore possible that this memory will be reused in any of the
subsequent allocations.
I answered make p = NULL.
No, it doesn't make any difference as far as the memory block itself is
concerned.
But again the interviewer was probably
expecting different answer as the debate went on thereafter...
The problem is that *nobody* really knows what the interviewer might
expect if he's asking such questions. :)
So is there any such thing like making sure that the deallocated(or
freeed) memory is returned to the heap?


The dynamic memory is either allocated or deallocated. Where it comes
from and where it goes is the allocator's business, but "heap" is indeed
a commonly used name for this place. This means that if we say that "new
allocates from the heap", then we can also say that "delete returns it
to the heap".

And, BTW, don't forget that new/delete is not only about memory: there
are also *objects* which are constructed and destructed in this memory.
--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 20 '06 #10

P: n/a

Rolf Magnus wrote:
mlimber wrote:

If the code makes it to the delete[] statement and the address held by
p has not been changed, it will certainly be freed (or "returned to the
heap") unless the global new[] and delete[] operators were overloaded
to do something different than the usual operators. Making the pointer
NULL afterwards has no effect on the heap, but it is good practice if
the pointer is still in scope in subsequent code.


I'd say it's not generally good practice, because it might hide double
deletion errors.


Double deletion errors hide themselves quite well already. I would
prefer they didn't bring down the software when they happen. Second,
and at least as important, you can't check the validity of a pointer if
you don't set invalid pointers to 0...the only check you can make is
equality to 0 or its good but if that pointer is deleted...BOOM!

DEFINATELY set pointers to 0. More time and effort will be saved with
this little thing than can ever be made up by "exposing" double
deletion errors.

Jan 20 '06 #11

P: n/a
On Fri, 20 Jan 2006 15:11:25 +0000 (UTC), ri******@gehennom.net
(Marcus Kwok) wrote:
Bob Hairgrove <in*****@bigfoot.com> wrote:
On 20 Jan 2006 05:29:51 -0800, "mlimber" <ml*****@gmail.com> wrote:
make p a "char*const" instead of "char*"


Why?


I imagine it's to avoid a situation like:

p = new char[1000];
++p;
delete [] p;

which is probably UB, since the address passed to delete[] is no longer
the address obtained from new[].


But then you cannot set p = 0 after the delete[], either.

--
Bob Hairgrove
No**********@Home.com
Jan 20 '06 #12

P: n/a
On 20 Jan 2006 05:29:51 -0800, "mlimber" <ml*****@gmail.com> wrote:
make p a "char*const" instead of "char*"
Bob Hairgrove <in*****@bigfoot.com> wrote: Why?

On Fri, 20 Jan 2006 15:11:25 +0000 (UTC), ri******@gehennom.net
(Marcus Kwok) wrote:I imagine it's to avoid a situation like:

p = new char[1000];
++p;
delete [] p;

which is probably UB, since the address passed to delete[] is no longer
the address obtained from new[].

Bob Hairgrove <in*****@bigfoot.com> wrote: But then you cannot set p = 0 after the delete[], either.


True, I forgot about that. So I guess you have to pick one and remember
not to do the other :)

--
Marcus Kwok
Jan 20 '06 #13

P: n/a
In article <11*********************@f14g2000cwb.googlegroups. com>,
yo******@gmail.com wrote:
Hello All,

I was asked a question in an interview..

Its related to dynamically allocated and deallocated memory.

eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?
Make 'p' a vector:

vector<char> p(1000);
I answered make p = NULL.But again the interviewer was probably
expecting different answer as the debate went on thereafter...
That would not accomplish what the interviewer asked.
So for me my knoweldge about dynamically allocated and deallocated
memroy starts with new and ends with delete...
So is there any such thing like making sure that the deallocated(or
freeed) memory is returned to the heap?


He was basically asking you "what can happen in the '...' code that
would cause the 'delete [] p' line to never be reached?" If he had asked
that, you probably would have done better.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 20 '06 #14

P: n/a
Bob Hairgrove wrote:
Bob Hairgrove <in*****@bigfoot.com> wrote:
On 20 Jan 2006 05:29:51 -0800, "mlimber" <ml*****@gmail.com> wrote:

make p a "char*const" instead of "char*"

Why?


I imagine it's to avoid a situation like:

p = new char[1000];
++p;
delete [] p;

which is probably UB, since the address passed to delete[] is no longer
the address obtained from new[].


But then you cannot set p = 0 after the delete[], either.


Why would you want to set it to 0 anyway? In other situations, it might make
sense, but you can't let the pointer point to something else (i.e. you
can't allocate another array and let it point to that array) so you can't
use p after the deletion anyway.

Jan 20 '06 #15

P: n/a
ro**********@gmail.com wrote:

Rolf Magnus wrote:
mlimber wrote:
> If the code makes it to the delete[] statement and the address held by
> p has not been changed, it will certainly be freed (or "returned to the
> heap") unless the global new[] and delete[] operators were overloaded
> to do something different than the usual operators. Making the pointer
> NULL afterwards has no effect on the heap, but it is good practice if
> the pointer is still in scope in subsequent code.


I'd say it's not generally good practice, because it might hide double
deletion errors.


Double deletion errors hide themselves quite well already. I would
prefer they didn't bring down the software when they happen.


Well, I prefer a crash that shows me that there is an error (and in a
debugger even where it is). After all, an error that you might not see is
still an error and can bite back later when you don't expect it.
Second, and at least as important, you can't check the validity of a
pointer if you don't set invalid pointers to 0...


That's why I said it's "not generally good practice" rather than "generally
not good practice". Sometimes, you need it.

Jan 20 '06 #16

P: n/a

Rolf Magnus wrote:
ro**********@gmail.com wrote:

Double deletion errors hide themselves quite well already. I would
prefer they didn't bring down the software when they happen.


Well, I prefer a crash that shows me that there is an error (and in a
debugger even where it is). After all, an error that you might not see is
still an error and can bite back later when you don't expect it.


I find this kind of bug very difficult to narrow onto. Usually what
ends up happening is you make a call to some member function because
your check for 0 said the pointer was valid (or you deleted a random
pointer - same diff). Then you go looking in the debugger and the
place you are at is nowhere near where the pointer was originally
deleted and your are very lucky if it is even anywhere in the call
stack. What is worse is that the pointer generally has what looks like
a legitamate value, because it was at one time (unlike when your
pointer is just uninitialized - MSCV gives it a caca value). Even in
small systems these problems can take hours of frustration to track
down when setting the ptr to 0 would have caused it to never happen.

Now, deleting a pointer twice *can* be indicative of a logic error but
is not dangerous in and of itself; in fact if you set your pointer to 0
it can't even happen short of an overload of delete. If attempting to
delete the pointer twice is the only thing that goes wrong then who
cares? Not setting to 0 won't protect you from this anyway - it will
only do so if your problem happens on a regular basis...but those
obscure bugs that turn up post sale that crash the system are just icky
- setting to 0 at least you can check your pointers.

I honestly can't think of many situations in which not setting to 0
could be anything but incredibly costly in debug time; well of course
if the ptr immediately goes out of scope it is rather redundant but I'm
talking about long lived ptrs. Usually what happens is some developer
decides that they don't need to set to 0 because the pointer will never
be accessed again...then someone comes along and accesses it, prudently
checking for 0 first, and the program just crashes. I've spent many
many hours on such things. Setting your pointers to 0 when they are
not valid (not just on delete) saves hours and hours of debug time and
is the first, most important, fundamental, *habit* to get into when
using them.

Jan 20 '06 #17

P: n/a
ro**********@gmail.com wrote:
Now, deleting a pointer twice *can* be indicative of a logic error but
is not dangerous in and of itself; in fact if you set your pointer to 0
it can't even happen short of an overload of delete. If attempting to
delete the pointer twice is the only thing that goes wrong then who
cares?


Deleting a pointer twice is UB [FAQ 16.2].

However, attempting to delete a 0 pointer is allowed and has no effect
[FAQ 16.8].

--
Marcus Kwok
Jan 20 '06 #18

P: n/a

Marcus Kwok wrote:
ro**********@gmail.com wrote:
Now, deleting a pointer twice *can* be indicative of a logic error but
is not dangerous in and of itself; in fact if you set your pointer to 0
it can't even happen short of an overload of delete. If attempting to
delete the pointer twice is the only thing that goes wrong then who
cares?
Deleting a pointer twice is UB [FAQ 16.2].


Which only further emphasizes my point. Nothing says the program has
to crash or do anything remotely obvious or immediate.

However, attempting to delete a 0 pointer is allowed and has no effect
[FAQ 16.8].

--
Marcus Kwok


Jan 20 '06 #19

P: n/a
On Fri, 20 Jan 2006 18:01:33 +0100, Rolf Magnus <ra******@t-online.de>
wrote:
Why would you want to set it to 0 anyway? In other situations, it might make
sense, but you can't let the pointer point to something else (i.e. you
can't allocate another array and let it point to that array) so you can't
use p after the deletion anyway.


Why not? While I can't use it for the array that I just deleted, I
should certainly be able to allocate another array, set the pointer to
point to that array and use it. But only if it is not a const pointer.

--
Bob Hairgrove
No**********@Home.com
Jan 20 '06 #20

P: n/a
ro**********@gmail.com wrote:

Marcus Kwok wrote:
ro**********@gmail.com wrote:
> Now, deleting a pointer twice *can* be indicative of a logic error but
> is not dangerous in and of itself; in fact if you set your pointer to 0
> it can't even happen short of an overload of delete. If attempting to
> delete the pointer twice is the only thing that goes wrong then who
> cares?


Deleting a pointer twice is UB [FAQ 16.2].


Which only further emphasizes my point. Nothing says the program has
to crash or do anything remotely obvious or immediate.


Nothing says your program will operate correctly after that point
either.

Deleting pointers twice: Just Say "No"!

--
Marcus Kwok
Jan 20 '06 #21

P: n/a
In article <dq*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote:
Double deletion errors hide themselves quite well already. I would
prefer they didn't bring down the software when they happen.


Well, I prefer a crash that shows me that there is an error (and in a
debugger even where it is). After all, an error that you might not see is
still an error and can bite back later when you don't expect it.


Want to make sure you never have double deletion errors? Set the pointer
to NULL after the delete.

"delete p; delete p;" is a double deletion, "delete p; p = NULL; delete
p;" is NOT a double deletion...
--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Jan 21 '06 #22

P: n/a
Daniel T. wrote:
In article <dq*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote:
> Double deletion errors hide themselves quite well already. I would
> prefer they didn't bring down the software when they happen.
Well, I prefer a crash that shows me that there is an error (and in a
debugger even where it is). After all, an error that you might not see is
still an error and can bite back later when you don't expect it.


Want to make sure you never have double deletion errors? Set the pointer
to NULL after the delete.


No. This just treats a symptom, not the actual illness.
"delete p; delete p;" is a double deletion, "delete p; p = NULL; delete
p;" is NOT a double deletion...


Well, it is still a bug, no matter how you call it. After I delete an
object, I assume that it doesn't exist anymore. If you have another delete
at a late point for the same object, that often (not always) means there is
some problem in the code, because it assumes the object is still existing,
even though it already has been deleted.
Jan 21 '06 #23

P: n/a
Bob Hairgrove wrote:
On Fri, 20 Jan 2006 18:01:33 +0100, Rolf Magnus <ra******@t-online.de>
wrote:
Why would you want to set it to 0 anyway? In other situations, it might
make sense, but you can't let the pointer point to something else (i.e.
you can't allocate another array and let it point to that array) so you
can't use p after the deletion anyway.
Why not?


For the same reason you can't set it to 0: Because the pointer is const.
While I can't use it for the array that I just deleted, I should certainly
be able to allocate another array, set the pointer to point to that array
and use it. But only if it is not a const pointer.


Uhm, yes. We were talking about what you can and can't do with a _const_
pointer, so my answer was of couse also just about that.

Jan 21 '06 #24

P: n/a
> eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end

The quesiton was..How will I be sure the deallocated memory is returned
to heap?


This question might be to do with exception safety, and what is really being
asked is, "how can I guarantee that delete [] p will be executed if an
exception occurs between new[] and delete[]?" Something like

char * p = new char[1000];
try
{

}
catch(...)
{
delete [] p;
throw;
}
delete [] p;

will guard against this but it is messy and better still would be to
re-write using vector<char> as that will make the try-catch(...) redundant.

Stephen Howe

Stephen Howe

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 21 '06 #25

P: n/a
In article <dq*************@news.t-online.com>,
Rolf Magnus <ra******@t-online.de> wrote:
Daniel T. wrote:
"delete p; delete p;" is a double deletion, "delete p; p = NULL; delete
p;" is NOT a double deletion...


Well, it is still a bug, no matter how you call it. After I delete an
object, I assume that it doesn't exist anymore. If you have another delete
at a late point for the same object, that often (not always) means there is
some problem in the code, because it assumes the object is still existing,
even though it already has been deleted.


Nonsense. The only time you are assuming that an object exists, is when
you dereference the pointer without first checking for null. 'delete'
always checks for null so it never assumes the object still exists.

"delete p; p = NULL; delete p;" has no bugs in it. "delete p; p = NULL;
*p;" has a bug... One that most debugging systems will catch.

By guarding against double deletion, you are guarding against the wrong
thing. What you need to guard against is dereference of a invalid
pointer.

--
Magic depends on tradition and belief. It does not welcome observation,
nor does it profit by experiment. On the other hand, science is based
on experience; it is open to correction by observation and experiment.
Jan 21 '06 #26

P: n/a
yo******@gmail.com wrote:
I answered make p = NULL.But again the interviewer was probably
expecting different answer as the debate went on thereafter...


The interviewer was probably thinking of exception-safety. If an
exception is thrown between the new and delete operations, then p
is not released.

There are several solutions. Which one is the best depends on the
exact details of the code in question.

1. Place the array on the stack rather than on the heap.
2. Use try-catch.
3. Use smart pointers.

--
mail1dotstofanetdotdk

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 22 '06 #27

P: n/a
Funny thing is that if you are looking at/for a trick question/answer.

Strickly speaking the heap is the default location for allocated
memory.
Strickly speaking New/Delete (malloc/free) do not remove or put memory
on the heap. They manage a Free List of memory that is available on
the Heap and if that is insufficient they request additional memory
from the Operating System to be placed on/in the Heap.

That said, the memory was never removed from the Heap (assuming it was
there to begin with) in which case there is nothing that needs to be
done to return the memory to the heap.

All of the above is applicable for the memory being returned to the
Free list.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 22 '06 #28

P: n/a

Rolf Magnus wrote:
Bob Hairgrove wrote:
Bob Hairgrove <in*****@bigfoot.com> wrote:
On 20 Jan 2006 05:29:51 -0800, "mlimber" <ml*****@gmail.com> wrote:

>make p a "char*const" instead of "char*"

Why?

I imagine it's to avoid a situation like:

p = new char[1000];
++p;
delete [] p;

which is probably UB, since the address passed to delete[] is no longer
the address obtained from new[].


But then you cannot set p = 0 after the delete[], either.


Why would you want to set it to 0 anyway? In other situations, it might make
sense, but you can't let the pointer point to something else (i.e. you
can't allocate another array and let it point to that array) so you can't
use p after the deletion anyway.


You can certainly try. "p[22] = 'a';" or in the case of objects
p->whatever(). If p never leaves the scope of some small block then it
is of no concern, but any time the scope of p extends beyond then these
techniques are not viable; you need to be able to set that pointer to 0
so that it can be verified.

Jan 23 '06 #29

P: n/a
Maciej Sobczak wrote:
yo******@gmail.com wrote:
I was asked a question in an interview.. Its related to dynamically allocated and deallocated memory. eg.
//start
char * p = new char[1000];
..
...
delete [] p;
//end The quesiton was..How will I be sure the deallocated memory
is returned to heap?
[...] I answered make p = NULL. No, it doesn't make any difference as far as the memory block
itself is concerned.
Actually, that's implementation defined. In fact, in the
implementation I use most of the time in my private work (g++
with the Boehm collection, the operator delete() function
replaced with a no-op), it does make a difference.

I don't know why, but for some reason, I don't think that that's
the sort of answer the interviewer was looking for. (If I were
the interviewer, and the interviewee didn't start his answer
with something along the lines of "well, using the Boehm
collector...", I don't think I'd accept it either.)
But again the interviewer was probably expecting different
answer as the debate went on thereafter...

The problem is that *nobody* really knows what the interviewer
might expect if he's asking such questions. :)
Quite:-).

[...] And, BTW, don't forget that new/delete is not only about
memory: there are also *objects* which are constructed and
destructed in this memory.


Except that given the way the question was formulated, one
rather imagines that the use of char here is intentional, to
ensure that this issue doesn't come into play.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 23 '06 #30

P: n/a
Stephen Howe wrote:
This question might be to do with exception safety, and what is really
being asked is, "how can I guarantee that delete [] p will be executed if
an exception occurs between new[] and delete[]?" Something like

char * p = new char[1000];
try
{

}
catch(...)
{
delete [] p;
throw;
}
delete [] p;

will guard against this but it is messy and better still would be to
re-write using vector<char> as that will make the try-catch(...)
redundant.


Or - more general - use the RAII technique, i.e. let a class do the
allocation/deallocation automatically. This can be a smart pointer or
std::vector<char> or something similar.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 23 '06 #31

P: n/a
ra******@gmail.com wrote:
Strickly speaking the heap is the default location for allocated
memory.
Strictly speaking, the word "heap" has another meaning in C++. What you are
talking about is called the free or dynamic storage.
Strickly speaking New/Delete (malloc/free) do not remove or put memory
on the heap. They manage a Free List of memory that is available on
the Heap and if that is insufficient they request additional memory
from the Operating System to be placed on/in the Heap.


This may be the case, or it may be not. The way how memory is handled by
new/delete or malloc/free depends on the target platform. Remember that
there are C++ compilers for architectures that don't even have an operating
system.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 23 '06 #32

P: n/a
On 22 Jan 2006 22:16:42 -0800, ro**********@gmail.com wrote:
you can't use p after the deletion anyway.


You can certainly try. "p[22] = 'a';" or in the case of objects
p->whatever(). If p never leaves the scope of some small block then it
is of no concern, but any time the scope of p extends beyond then these
techniques are not viable; you need to be able to set that pointer to 0
so that it can be verified.


You can *try* just about anything. But after "delete p;" it's always
undefined behavior to do what you suggest, regardless of what the
scope of p might be (see sec. 5.3.5, paragraph 4 of the standard).

--
Bob Hairgrove
No**********@Home.com
Jan 23 '06 #33

P: n/a

Rolf Magnus wrote:
ra******@gmail.com wrote:
Strickly speaking the heap is the default location for allocated
memory.


Strictly speaking, the word "heap" has another meaning in C++. What you are
talking about is called the free or dynamic storage.


You can point that out to the interviewer as an afterthought, but my
answer in an interview would be first to ideally use vector[char] (or
even string) or a smart-pointer (but beware it can't be auto_ptr or
boost::shared_ptr which don't do delete[]) but without using those, to
use catch(...) { delete[] p; throw; } workaround.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 24 '06 #34

P: n/a
> Or - more general - use the RAII technique, i.e. let a class do the
allocation/deallocation automatically. This can be a smart pointer or
std::vector<char> or something similar.


Yes agreed. The try-catch solution is just plain ugly.
I still think OP's question had exception safety in mind.

Stephen Howe

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 24 '06 #35

P: n/a
In article <11**********************@o13g2000cwo.googlegroups .com>,
Earl Purple <ea********@gmail.com> wrote:
Rolf Magnus wrote:
ra******@gmail.com wrote:
Strickly speaking the heap is the default location for allocated
memory.


Strictly speaking, the word "heap" has another meaning in C++. What you are
talking about is called the free or dynamic storage.


You can point that out to the interviewer as an afterthought, but my
answer in an interview would be first to ideally use vector[char] (or
even string) or a smart-pointer (but beware it can't be auto_ptr or
boost::shared_ptr which don't do delete[]) but without using those, to
use catch(...) { delete[] p; throw; } workaround.

a boost or tr1 shared_ptr CAN call delete [] upon destruction.

struct array_deleter
{
template <class T> operator ()(T *p){delete [] p;}
};

boost::shared_ptr<char> p(new char[100],array_deleter());
although for a buffer I'd probably use std::vector<char> myself,
unless the shared semantics made sense or the copying process is too
slow with vector.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 24 '06 #36

P: n/a

Carl Barron wrote:
a boost or tr1 shared_ptr CAN call delete [] upon destruction.

struct array_deleter
{
template <class T> operator ()(T *p){delete [] p;}
};

boost::shared_ptr<char> p(new char[100],array_deleter());
although for a buffer I'd probably use std::vector<char> myself,
unless the shared semantics made sense or the copying process is too
slow with vector.


yes of course, and that's how my own shared_ptr works as it happens if
you want to delete arrays (and it's used in my portable_string class).

You can't specify a deleter with boost::scoped_ptr though (but there is
boost::scoped_array). With this particular case you'd probably want
scoped_array because you're not sharing with anything (albeit that
shared_ptr will work with your array_deleter).

And practically are you really going to write your functor here? (It
doesn't check for completeness and I'm not 100% sure boost will do that
for you with your own deleter, although on this occasion T is char).
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jan 24 '06 #37

P: n/a

Bob Hairgrove wrote:
On 22 Jan 2006 22:16:42 -0800, ro**********@gmail.com wrote:
you can't use p after the deletion anyway.


You can certainly try. "p[22] = 'a';" or in the case of objects
p->whatever(). If p never leaves the scope of some small block then it
is of no concern, but any time the scope of p extends beyond then these
techniques are not viable; you need to be able to set that pointer to 0
so that it can be verified.


You can *try* just about anything. But after "delete p;" it's always
undefined behavior to do what you suggest, regardless of what the
scope of p might be (see sec. 5.3.5, paragraph 4 of the standard).


Not if p == 0.

Jan 24 '06 #38

This discussion thread is closed

Replies have been disabled for this discussion.