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

Y

yogpjosh

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! ]
 
P

PasalicZaharije

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
 
M

mlimber

[Cross-posting deleted]

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
 
R

Rolf Magnus

mlimber said:
[Cross-posting deleted]

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

Marcus Kwok

Bob Hairgrove said:

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[].
 
D

Daniel T.

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.[/QUOTE]

Such a construct is unnecessary. A vector would do the job just fine.
 
G

Gavin Deane

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! ]
 
M

Maciej Sobczak

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! ]
 
K

kanze

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! ]
 
R

roberts.noah

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

Bob Hairgrove

Bob Hairgrove said:

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

Daniel T.

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 said:
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! ]
 
M

Marcus Kwok

Bob Hairgrove said:
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 said:
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 :)
 
R

Rolf Magnus

Bob said:
Bob Hairgrove said:
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.
 
R

Rolf Magnus

Rolf said:
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.
 
R

roberts.noah

Rolf said:
(e-mail address removed) wrote:

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

Marcus Kwok

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].
 
R

roberts.noah

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

Bob Hairgrove

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.
 

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

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top