Delete Question...

Started by
6 comments, last by Elwren 22 years, 9 months ago
Hey, I''m reading this C++ book and one of the chapters is discussing templates. So as I''m reading it and coding the examples, I''m getting an "Debug Assertion Failed!" error with the expression "_BLOCK_TYPE_IS_VALID(pHead->nBlockUse". So I copied and paste the code from the book, and get the same exact error. I''m not good with the Debugging mode in VC++, but I believe the problem is the very last part the program, where I am deleting theZoo. The author uses a for loop and deletes it in a weird way, one that I''ve never seen before, so I''m not really sure what the problem is. I tried to take out the weird for/delete loop, and just put my normal way of deleting an array, delete [] theZoo;, but I get some conversion error. Anyways, could someone take a look at this code and explain what the problem is and why the author deleting theZoo in the way that he did. Thanks
  
   #include <iostream.h>
   const int DefaultSize = 10;
   // declare a simple Animal class so that we can

   // create an array of animals

   class Animal
   {
   public:
      Animal(int);
      Animal();
      ~Animal() {}
      int GetWeight() const { return itsWeight; }
       void Display() const { cout << itsWeight; }
   private:
      int itsWeight;
   };
   Animal::Animal(int weight):
   itsWeight(weight)
   {}
   Animal::Animal():
   itsWeight(0)
   {}
   template <class T>  // declare the template and the parameter

   class Array            // the class being parameterized

    {
   public:
       // constructors

       Array(int itsSize = DefaultSize);
       Array(const Array &rhs);
      ~Array() { delete [] pType; }

      // operators

       Array& operator=(const Array&);
      T& operator[](int offSet) { return pType[offSet]; }
      const T& operator[](int offSet) const 
          { return pType[offSet]; }
       // accessors

      int GetSize() const { return itsSize; }
    private:
      T *pType;
       int  itsSize;
   };
   // implementations follow...

   // implement the Constructor

   template <class T>
   Array<T>::Array(int size = DefaultSize):
   itsSize(size)
   {
      pType = new T[size];
      for (int i = 0; i<size; i++)
         pType[i] = 0;
   }
   // copy constructor

   template <class T>
   Array<T>::Array(const Array &rhs)
   {
      itsSize = rhs.GetSize();
      pType = new T[itsSize];
      for (int i = 0; i<itsSize; i++)
         pType[i] = rhs[i];
   }
   // operator=

   template <class T>
   Array<T>& Array<T>::operator=(const Array &rhs)
   {
      if (this == &rhs)
         return *this;
      delete [] pType;
      itsSize = rhs.GetSize();
      pType = new T[itsSize];
      for (int i = 0; i<itsSize; i++)
         pType[i] = rhs[i];
      return *this;
   }
   // driver program

   int main()
   {
      Array<int> theArray;      // an array of integers

      Array<Animal> theZoo;     // an array of Animals

      Animal *pAnimal;
      // fill the arrays

      for (int i = 0; i < theArray.GetSize(); i++)
      {
         theArray[i] = i*2;
         pAnimal = new Animal(i*3);
         theZoo[i] = *pAnimal;
           delete pAnimal;
     }
     // print the contents of the arrays

     for (int j = 0; j < theArray.GetSize(); j++)
     {
        cout << "theArray[" << j << "]:\t";
        cout << theArray[j] << "\t\t";
        cout << "theZoo[" << j << "]:\t";
        theZoo[j].Display();
        cout << endl;
     }
      for (int k = 0; k < theArray.GetSize(); k++)
        delete &theZoo[j];
    return 0;
}
  
Advertisement
After a quick look:

theZoo is an array of Animals, not pointers to animal.



What the hells!
What the hells!
It looks as though theZoo is an array and to delete it the author is referencing theZoo to get its address and through the for loop is incrementing it to delete all values of the array. My best guess for the reason a delete [] theZoo would not work is because theZoo points to the first part of the array and with that syntax u are telling it to delete an array when it is actually a single pointer, i think, thats why he uses the for loop. Don''t quote me on that I am still kind of new at C++ but thats what I got from it.

Chris
In the book, the author says something about "returning the allocated memory before the arrays are destroyed". What does this mean?

Also, why does he delete the address of the last instance of the array of objects (he put the already incremented variable ''j'' in theZoo[j] instead of ''k'')
Well returning the allocated memory before the arrays are destroyed means to go through each element of your array and free the memory that was allocated for each element before you free the array itself. Otherwise the memory for each element will be hogged forever(or atleast until reboot) if it manages to slip by Windows on exit

Did you try replacing that j with a k?

I think it should be a k. Trying to delete something that was already deleted will generally cause problems

Seeya
Krippy
Ya I tried changing it to a ''k'' and it still got the same error. Is it safe to run this program and encountring the error, because I don''t want to hog up a portion of my memory "forever". =( If anyone could tell me how to delete the memory in a different way than the author is doing it, than that would be fine too. Thanks
After looking at that code closer, I have come to the conclusion that you should find a different book to read. lol. This author is nuts.

That last loop encompasses all kinds of issues.

First, even though we are pretty sure theArray and theZoo contain the same number of elements, using the size of theArray rather than the size of theZoo to iterate through the elements of theZoo is madness and breaks numerous rules of programming etiquette.

Second, the j in the array bounds makes absolutely no sense at all.

Third, the reason he puts the & before theZoo[j] is because theZoo[j] returns a reference, not a pointer. Therefore, he is trying to delete a reference which is not going to happen. If you don''t put the & first you will get an error about converting '''' to something, so putting the & in front allows the program to compile but not function properly. He probably never tested that it worked, just hacked it together so that it would compile. That would also explain his not noticing the misplaced j.
That line is pretty much eqivalent to this:
Animal an = theZoo[j];
delete &an

which is a big no-no.


Fourth, the loop is completely unnecessary. In the destructor for Array he has this:

delete [] pType;

Which does exactly what he is attempting to do in that loop. It iterates through each instance of Animal in the array and deletes them. That is the purpose of the delete [] syntax instead of simply delete.

Therefore, if the program somehow was able to delete those instances in his loop, it would certainly fail in the destructor where it will attempt to delete things which were already deleted unless you were to set them as NULL after you delete them (which he doesn''t attempt to do).

So you can safely remove that loop from your program and be done with it

Seeya
Krippy
Woo hoo, I took out the loop at the end like you said and it worked fine. Thanks so much, I''ve been stuck on the same chapter for like 4 days.

Oh and the book I''m reading is "Teach Yourself C++ in 21 Days" and I''m currently on day 19; up to this point, the code has been pretty good so all and all, its a pretty decent book for beginners.

Thanks again for the help, peace

This topic is closed to new replies.

Advertisement