Solved

trouble with new

Posted on 1998-06-24
30
232 Views
Last Modified: 2010-04-01
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!
0
Comment
Question by:Booth882
  • 13
  • 12
  • 2
  • +3
30 Comments
 

Expert Comment

by:t004024
ID: 1166610
Do U have code in U'r constructor for class T, it maybe giving access violation in the constructor.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1166611
Please email me the whole code to find the reason. You can find my email address from my homepage.

0
 
LVL 22

Expert Comment

by:nietod
ID: 1166612
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:Booth882
ID: 1166613
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
 
LVL 1

Author Comment

by:Booth882
ID: 1166614
the trouble is in the GrowTheArray function when I declare TempT to be a new T[TempLength].
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166615
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166616
Opps.  I'm wrong.  I thought I saw a mistake.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166617
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
 
LVL 22

Expert Comment

by:nietod
ID: 1166618
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
 
LVL 22

Expert Comment

by:nietod
ID: 1166619
Another unrelated problem, Inside shrinkthearray you have "delete TheArray;" it should be "delete [] TheArray;".
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166620
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
 
LVL 1

Author Comment

by:Booth882
ID: 1166621
no sweat.  I'll check out your comments and be back
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166622
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
 
LVL 1

Author Comment

by:Booth882
ID: 1166623
i fixed the others.  thanks
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166624
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
 
LVL 22

Expert Comment

by:nietod
ID: 1166625
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
 
LVL 11

Expert Comment

by:alexo
ID: 1166626
void main()
{
    array<int> TheArray(4);
    array<int> TheOtherArray(6);
    TheArray = TheOtherArray;
}

Ran perfectly for me.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166627
really? wow, I'll check that out
0
 
LVL 3

Expert Comment

by:danny_pav
ID: 1166628
why not just use the vector out of the STL?
0
 
LVL 11

Expert Comment

by:alexo
ID: 1166629
Maybe because it's a homework assignment?
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166630
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
 
LVL 1

Author Comment

by:Booth882
ID: 1166631
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
 
LVL 22

Expert Comment

by:nietod
ID: 1166632
>> 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
 
LVL 22

Expert Comment

by:nietod
ID: 1166633
I ran this under VC an it detected a corrupted heap.  I'll look a little closer.
0
 
LVL 22

Accepted Solution

by:
nietod earned 110 total points
ID: 1166634
I see the problem.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166635
to each his own, I guess.  it's just the way I like to do it.

corrupted heap? what does that mean?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166636
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
 
LVL 22

Expert Comment

by:nietod
ID: 1166637
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
 
LVL 1

Author Comment

by:Booth882
ID: 1166638
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
 
LVL 1

Author Comment

by:Booth882
ID: 1166639
thanks nietod you have once again saved the day.  
0

Featured Post

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question