trouble with new

in my array template class of type 'T' I have the following line:

T * TempTArray = new T[TempTLength];

I have used the debugger to pinpoint this line as the trouble.  It goes to the new operator code to allocate memory, and somewhere in the middle of it I get the following error:

"unhandled exception in arraytest.exe:0xC000005: Access Violation"

and sends me to KERNEL32!bff782af( ) with the yellow arrow that says which line the error occured in pointing at the line, in assembly:

mov    pword ptr[ecx + 08], eax

Please tell me what is going on!
LVL 1
Booth882Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

t004024Commented:
Do U have code in U'r constructor for class T, it maybe giving access violation in the constructor.
0
trestanCommented:
Please email me the whole code to find the reason. You can find my email address from my homepage.

0
nietodCommented:
Why don't you post the code for the class's default constructor here.  We only need to see the default constructor (not any others), and any functions it calls.
0
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

Booth882Author Commented:
here is the array class in its entireity

#ifndef __array_h
#define __array_h

template <class T>
class array
{
private:
      T * TheArray;
      int TheLength;
public:
      array(int InitialLength);
      ~array();

      array & operator=(array & ArrayReference);
      T & operator[](int Offset);
      
      int GetTheLength(){return TheLength;};
      T * GetTheArray(){return TheArray;};
      void GrowTheArray(int AmountOfGrowth);
      void ShrinkTheArray(int AmountOfShrank);
      void AddToArray(T & TReference);
};

template <class T>
array<T>::array(int InitialLength)
{
      TheLength = InitialLength;
      TheArray = new T[TheLength];
      for(int hon = 0; hon < TheLength; hon++)
            TheArray[hon] = 0;
}

template <class T>
array<T>::~array()
{
      delete [] TheArray;
      TheArray = 0;
}

template <class T>
array<T> & array<T>::operator=(array<T> & ArrayReference)
{
      int TheDifference = (ArrayReference.GetTheLength() - TheLength);
      if(TheDifference > 0)
      {
            GrowTheArray(TheDifference);
            TheLength = ArrayReference.GetTheLength();
      }
      if(TheDifference < 0)
      {
            ShrinkTheArray(0 - TheDifference);
            TheLength = ArrayReference.GetTheLength();
      }
      
      for(int Pount = 0; Pount < TheLength; Pount++)
            TheArray[Pount] = ArrayReference[Pount];
      
      return *this;
}

template <class T>
T & array<T>::operator[](int Offset)
{
      return TheArray[Offset];
}

template <class T>
void array<T>::GrowTheArray(int GrowthAmount)
{
      int TempLength = TheLength + GrowthAmount;
      T * TempT = new T[TempLength];

      for(int i = 0; i < TheLength; i++)
            TempT[i] = TheArray[i];
      for(int u = TheLength; u < TempLength; u++)
            TempT[u] = 0;

      delete [] TheArray;
      TheArray = TempT;
      TheLength = TempLength;
}

template <class T>
void array<T>::ShrinkTheArray(int AmountOfShrank)
{
      int TempLength = TheLength - AmountOfShrank;
      if(TempLength < 1)
            return;
      T * TempT = new T[TempLength];

      for(int h = 0; h < TempLength; h++)
            TempT[h] = TheArray[h];

      delete TheArray;
      TheArray = TempT;
      TheLength = TempLength;
}

template<class T>
void array<T>::AddToArray(T & TReference)
{
      GrowTheArray(1);
      TheArray[TheLength - 1] = TReference;
}

#endif

hope this helps!
0
Booth882Author Commented:
the trouble is in the GrowTheArray function when I declare TempT to be a new T[TempLength].
0
nietodCommented:
answer coming.
0
nietodCommented:
Opps.  I'm wrong.  I thought I saw a mistake.
0
nietodCommented:
If growamount was negative the function would crash.  Are you sure that is not the case?  You could put in an assert to make sure.
0
nietodCommented:
Not related to the problem, but inside the operator = function, you sent the array length after calling GrowTheArray and ShrinkTheArray() that is not needed.  These functions change the array length.
0
nietodCommented:
Another unrelated problem, Inside shrinkthearray you have "delete TheArray;" it should be "delete [] TheArray;".
0
nietodCommented:
What type are you instanciating the template for?  I suspect this type has a problem in its constructor.  Can you create the template using a simple type like "int".  "int" has no constructors.  if the problem goes away with "int", but is there with a type that has constructors, I would look at the constructor for the type you are using.

Sorry to have locked this up.  I missread the two loops in the grow function and thought it was a mess.  It actually looks pretty good.
0
Booth882Author Commented:
no sweat.  I'll check out your comments and be back
0
Booth882Author Commented:
it doesnt work for an int or an array<int>.  I have tried them both.  The array<int> takes a value for it's constructor.  how would I phrase that?

typedef array<int> IntArray;

array<IntArray>  BigArray(2);

T * TempT = new array<T>(2)[10];

or

T * TempT = new array<T>[10](2);

where 2 is the parameter passed to the constructor and 10 is the size of the array.  How do I do that? it may be what's wrong.
0
Booth882Author Commented:
i fixed the others.  thanks
0
Booth882Author Commented:
that cant be the only problem though.  when I say:

array<int> TheArray(4);
array<int> TheOtherArray(6);

TheArray = TheOtherArray;

it gives me the same error.  the problem is in the new operator in GrowTheArray function called by the equals operator in this line:

T * TempT = new T [ TempLength ];

something goes wrong with the allocation.  I just dont know what it is.
0
nietodCommented:
Is

array<int> TheArray(4);
array<int> TheOtherArray(6);

TheArray = TheOtherArray;

the only think in the program?  i.e.  is that all that is in main?  When I create a program that just does that in main, it runs fine.  If your program is doing other things, you may have a problem elsewhere that is corrupting the heap and causing "new" to fail.  Can you reproduce the error in a program that does nothing but the above?
0
alexoCommented:
void main()
{
    array<int> TheArray(4);
    array<int> TheOtherArray(6);
    TheArray = TheOtherArray;
}

Ran perfectly for me.
0
Booth882Author Commented:
really? wow, I'll check that out
0
danny_pavCommented:
why not just use the vector out of the STL?
0
alexoCommented:
Maybe because it's a homework assignment?
0
Booth882Author Commented:
its not a homework assignment.  I like to use all my own classes, just because I know how they work intimately and can change them at will.  I would redo iostream and conio if only I knew how!
0
Booth882Author Commented:
you guys are right.  it works fine just like that.  here is a copy of my arraytest.cpp:

#include <iostream.h>
#include <conio.h>
#include <array.h>

typedef array<int> IntArray;

void Display(array<int> & TheArray)
{
for(int k = 0; k < TheArray.GetTheLength(); k++)
cout << TheArray[k] << " ";

getch();
}

void main()
{
array<int> AnArray(4);
array<int> OtherArray(6);
      
cout << "initializing AnArray" << endl;
for(int y = 1; y < 5; y++)
{
AnArray[y] = y;
cout << AnArray[y] << " ";
}
cout << endl;
getch();

cout << "initializing OtherArray" << endl;
for(int u = 8; u < 19; u += 2)
{
OtherArray[u] = u;
cout << OtherArray[u] << " ";
}
cout << endl;
getch();

cout << "administering equals test" << endl;
AnArray = OtherArray;
Display(AnArray);

cout << "calling AddToArray" << endl;
int TheInt = 88;
AnArray.AddToArray(TheInt);
Display(AnArray);
      
cout << "calling ShrinkTheArray" << endl;
AnArray.ShrinkTheArray(3);
Display(AnArray);
}


the problem is in the equals test when I say:

AnArray = OtherArray;

but when I comment out the initialization loops for AnArray and OtherArray at the beginning of main() it works just fine.  so setting the individual elements of the array to something corrupts the new operator in GrowTheArray?  I dont understand.  please tell me what you think
0
nietodCommented:
>> I like to use all my own classes

Very, very very stupid idea.  By the way,  I do it that way myself (Including the streams.)  Like you I want to know how they work internatlly, and I want them to work the way I want them to work.  But it probably is a bad idea al the same.

Does the problem reproduce in a simple program?  If not, you've got a corrupted heap.  In this case, there are ways to track down the source of the problem.  But it usually is a pain.  If you are using VC, it can help.  Another possibility is boundschecker.


0
nietodCommented:
I ran this under VC an it detected a corrupted heap.  I'll look a little closer.
0
nietodCommented:
I see the problem.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Booth882Author Commented:
to each his own, I guess.  it's just the way I like to do it.

corrupted heap? what does that mean?
0
nietodCommented:
The problem is you are using invalid indexes into the arrays.  You define "AnArray to have 4 elements, those are number from 0 to 3, but you initialize from 1 to 4. in the loop

for(int y = 1; y < 5; y++)
     {
     AnArray[y] = y;
     cout << AnArray[y] << " ";
     }

If you did

for(int y = 0; y < 4; y++)
     {
     AnArray[y] = y;
     cout << AnArray[y] << " ";
     }

you would be fine (until the next loop that does the same sort of thing.)

Now I'm wondering.  Are you trying to make your arrays numbered from one instead of from 0?  You can do that by having the code inside the operator [] procedure subtract one from the index.

In any case you might want to do an error check for invalid indexes (and other problems) in the class.  You can use conditional compilation to make sure the code is removed in the final version.  You will save yourself a lot of agrivation that way.
0
nietodCommented:
These comments are getting all out of order.  The heap is the memory pool (or pools) that the memory returned from new and malloc comes from.  It is gigantic data stucture with sections that are in use by your program (allocated by malloc or new) and sections that are free, in addition it has informaiton for managing this huge structure  (basically a linked list).  If you write past one of the ends of a block taken from the heap you will be causing problems.  if you are lucky you will just write over another block that is free.  Or you might over a block that you are using and cause a very weird error that shows up later.  However, what you were doing in this case, was writing over data used to manage the heap.  Thus when the run-time library when to search the heap for more free memory it died.
0
Booth882Author Commented:
Ahh, so simple.  I wanted the values to be from one to four, but the indexes from zero to three.  stupid mistake.  thanks I'll check it out and see if it works.
0
Booth882Author Commented:
thanks nietod you have once again saved the day.  
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.