Link to home
Start Free TrialLog in
Avatar of boodabelly
boodabelly

asked on

deallocating memory

Here is some sample code.  What is the proper way to use the "delete" keyword?  I just need to know if there is a more efficient way, or if this is even the proper way to release the memory back to the OS.

main ()
 {
  Mammal *mammals [ 2 ];  // base class pointer

  addMammals ( mammals );
  deleteMammals ( mammals );
 }

void addMammals ( Mammal **mammals )
 {
  mammals [ 0 ] = new Human ();   // set base class pointer to
                                  //derived class
  mammals [ 1 ] = new Whale();    // set base class pointer to
                                  //derived class
 }

void deleteMammals ( Mammal **mammals )
 {
  delete [] mammals;
  for ( int mamCounter; mamCounter < 2; mamCounter++ )
   {
    mammals [ mamCounter ] = NULL;
   }
 }
Avatar of boodabelly
boodabelly

ASKER

Edited text of question.
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> release the memory back to the OS
Delete doesn't really release memory back to the OS (at least not in windows implimentations of C++)  It releases the memory back to the C++ Run-time library (RTL). The memory returned by new comes from a "heap" which is a large block of memory that the RTL obtains from the OS.  the RTL then doles out portions of this block to your program when you request it with "new"   When you delete the memory, it still remains inside this block, so the RTL can then use it to satisfy future requests for memory.   (That's a bit simplified, but that is typically the basics of how new and delete work on most C++ implimentations.)

Now the first problem I see (which I miss-diagnosted before) is that you delete memory that is not allocated by new.

You delcare the array using

 Mammal *mammals [ 2 ];

This creates an array with 2 entries.  The array is not du=ynamically allocated.  That is, the array is not created with new.  Now the items stored in the arrayy are pointers.  There pointers could point to items that are allocated with new, but there is a big differenve between the array storing items allocated with new and the array itself being allocated with new.  Make sense?

So when you do

  delete [] mammals;

you are making a mistake.  the array was not allocaated with new, so it should not be deleted.  Okay?

continues
Now you do allocate two things with new, so those two things should be dealocated with delete.   so when you do

mammals [ 0 ] = new Human ();

You must later do

delete mammals[0];

And the same with the 2nd entry.

Another problem is the for loop

>> for ( int mamCounter; mamCounter < 2; mamCounter++ )

this declares mamCounter, but does not initialize it.  So that counte may start out with a value of -1, causeing the loop to rin 3 times (probably not un 3 times since it will probably crash before that.)  You want the coutner to start at 0 so do

 for ( int mamCounter = 0; mamCounter < 2; mamCounter++ )
Sorry for the code being sloppy, I am typing this while talking on the phone at work.  I meant to initialize the variables.  I see what you are saying about the array.  How do I set the pointer that was pointing to the new object to NULL so there is no dangling pointer.  Could I do this.

mammals [ 0 ] = NULL;

That would set the pointer to NULL right?  And this

delete mammals [ 0 ];

actually deletes the memory that the pointer points to?  Pointers are confusing but I think once you finally figure out how to use them correctly makes the programs function ten times better.  

The memory is being released by the program so that the memory can be used again, but not actually returned directly to the system?  If this isnt done then the memory cannot be accessed by any other program until the computer is restarted, right?
Just curious, we are developing programs for school that run under UNIX using the gcc compiler.  I was wanting to know if you wanted to take a look at it and see if you could port it to run under win98.  The programs compiles and runs fine under UNIX, but at last count using VC++ 6.0, when I compiled it, it contained almost 700 errors, mainly due to the fact that I am using the "string" data type and I am not sure what lib VC++ wants to support it.  I am using <string> under gcc to support it.  If you wanted to help me with it I will give you how ever many points you want.  Ive already turned the program in, I am just wanting to try and get this ported to win98.  Let me know and I will post a question and email you the project.
>> Could I do this.

>> mammals [ 0 ] = NULL;

>> That would set the pointer to NULL right?

Yes, that sets the pointer to NULL.  Now in most cases it is not necessary to do that.  in most cases when we are done using a dynamically allocated object we delete it, but let the pointer to it keeps its value.  this is okay as long as you don't use the pointer.  (as long as you don't dereference it.)   The only time you need to set the pointer to NULL is for cases where the pointer sometimes points to an object ans sometimes doesn't and this changes throughout the program and in some places you test to see if the pointer points to an object by seeing if it is not NULL.   Sot he code is correct, but usually not needed.

>> delete mammals [ 0 ];

>> actually deletes the memory that the
>> pointer points to?
Right.  

>> If this isnt done then the memory cannot be
>> accessed by any other program until the computer
>> is restarted, right?
This depends on the particular implimentation of C++ and the OS it is running on, but in windows, the memory will be returned to the OS when the program terminates.  When the program starts the RTL obtains a chunk of memory (virtual memory) from the OS and uses this as a heap. The malloc() procedure (and maybe others) allocates portions of the heap for use by the program.  When the program is finished, the heap as well as other meory used by the program is returned to the OS.  

>> "string" data type and I am
>> not sure what lib VC++ wants to support it.
string is part of the STL (standard template library) and VC supports it almost completely.  

>> I am using <string> under gcc
That is correct.  This is standard stuff that should be portable without changes to any up-to-date compiler.  (Any compiler that was written or modernized in the last 2 years.)

If I had to guess--and I do--I suspect the problem is that the gcc compiler is out of date and does not use namespaces.  VC does support namspaces, a more recent addition to the standard.  All of the STL library is placed in the "std" namespace, so in VC you will get errors if you do not specify the namespace name before anythign that comes from the STL, i.e "string" should be specified as "std::string".  gcc shoudl require this too, but old versions won't.  Since specifuing all these "std::"'s gets tedious, another option us to place a using delcaration in the source code, like

using namspace std;

after the using declaration you will not have to speicfy the "std::" anymore.
I tried
 
using namespace std;

in VC, but it says that no such namespace exists.
Then I'm not sure what the problem is.  I suspect that despite th nunber of errors it is something minor that can be corrected to get the code to work on both.

How long is the code?
its right around 690, most of the files are class definitions.  The main driver file is 159 lines.  thats probably too much to look at in your spare time, but if you want me to email it to you or for me to post it somewhere that you can download let me know.  Also let me know how many points you want when you get finished.
You can e-mail it to me.  My address is nietod@journey.com.  (it appears in my expert profile)

50pts is probably fair.